Page 1 of 2

<do_if value="not lib.units.combat?">

Posted: Sun, 2. Aug 15, 16:45
by w.evans
Been trying to get stations to buy drones. Been digging through the files, and so far, I've managed to narrow down what's needed to either:
  • writing lib.units.combat from scratch,
  • or expanding lib.ammo.missiles to also produce an order list for drones,
  • or requesting Ego to make a working command that will work similar to evaluate_ammo_storage, but for evaluating unit storage.
The first two appear doable, but I'm hesitating because I'm really not all that familiar with the trade commands. So, the question:

does anyone have a working lib.units.combat that you're willing to share?

edit: a working lib.units.trade would be useful, too, if anyone's built that.

Posted: Sun, 2. Aug 15, 16:48
by UniTrader
dont have one obviously, but drone capacity is shared for all, so just getting the current drones, total capacity, doing some math and creating trade offers which unbundle should do the trick i think..

Posted: Sun, 2. Aug 15, 16:51
by w.evans
UniTrader wrote:dont have one obviously, but drone capacity is shared for all, so just getting the current drones, total capacity, doing some math and creating trade offers which unbundle should do the trick i think..
Thanks, Uni. Yup, will be looking into doing that while hoping that someone already tried it and is willing to share. Even a failed attempt might be useful to begin with.

Posted: Sun, 2. Aug 15, 17:35
by euclid
It depends what drone type distribution you wish the defensible (ship, station) should have. For example to check if the defensible has 50% welder drones you can use the value:

Code: Select all

<set_value name="$Drones" exact="0.5*$Defensible.units.maxcount - $Defensible.units.{unitcategory.welder}.count" />
Hope that helps.

Cheers Euclid

Posted: Sun, 2. Aug 15, 17:44
by w.evans
Thanks, Euclid. Yeah, am using Ego's lib.ammo.missiles as a template and, so far, I have:

Code: Select all

      <!-- <evaluate_ammo_storage object="$object" type="missile" capacity="$launchercapacity" macros="$macrolist" amounts="$amountlist" wares="$warelist" /> -->
      <set_value name="$launchercapacity" exact="$object.units.{unitcategory.defence}.maxcount"/>
      <set_value name="$macrolist" exact="[macro.units_size_drone_attackdrone_impulse_mk1_macro, macro.units_size_drone_attackdrone_impulse_mk2_macro, macro.units_size_drone_attackdrone_plasma_mk1_macro, macro.units_size_drone_attackdrone_plasma_mk2_macro, macro.units_size_drone_missiledrone_dumbfire_mk1_macro, macro.units_size_drone_missiledrone_dumbfire_mk2_macro]"/>
      <set_value name="$amountlist" exact="$object.units.{unitcategory.defence}.maxcount - $object.units.{unitcategory.defence}.count"/>
      <set_value name="$warelist" exact="[drp_interceptor_mk1, drp_interceptor_mk2, drp_intrepid_mk1, drp_intrepid_mk2, drp_overrun_mk1, drp_overrun_mk2]"/>
to approximate the results of evaluate_ammo_storage. Don't know yet if these are the values that the rest of the script is expecting, though. Studying it, but am rather slow when initially getting into an unfamiliar script.

Which reminds me, I just remembered your station-building mod. Do you have anything in there that generates drone orders?

Posted: Sun, 2. Aug 15, 17:56
by euclid
w.evans wrote: ...*snip*....
Which reminds me, I just remembered your station-building mod. Do you have anything in there that generates drone orders?
The modified engineerai script in my TempZoneStationBuilder mod is doing the job. The station engineer checks for drones and ammo and replenish (best buy) if necessary. The engineers on all my ships (except the Skunk) running a similar routine from a modified engineerai script (not published).

Cheers Euclid

Posted: Sun, 2. Aug 15, 18:08
by w.evans
Thanks! I'll take a peek. If I find anything useful, may I adapt it and adopt into this?

Posted: Sun, 2. Aug 15, 18:32
by w.evans
So far:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<aiscript name="MICT.lib.units.combat" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="aiscripts.xsd" priority="1">
  <params>
    <param name="object" default="null" />
    <param name="configentity" default="null" />
    <param name="debugchance" default="0" />
  </params>
  <attention min="unknown">
    <actions>

      <do_if value="not $object.exists">
        <set_value name="$object" exact="this.defensible" />
      </do_if>

      <create_list name="$order_macrolist" />
      <create_list name="$order_warelist" />
      <create_list name="$order_pricelist" />
      <create_list name="$order_amountlist" />

      <!-- <evaluate_ammo_storage object="$object" type="missile" capacity="$launchercapacity" macros="$macrolist" amounts="$amountlist" wares="$warelist" /> -->
      <!--<set_value name="$maxcapacity" exact="$object.units.maxcount - 100"/>-->
      <set_value name="$launchercapacity" exact="$object.units.maxcount - 100"/>
      <!--<set_value name="$launchercapacity" exact="$maxcapacity - $object.units.count"/>-->
      <!--<set_value name="$launchercapacity" exact="$object.units.maxcount - $object.units.count"/>-->
      <set_value name="$macrolist" exact="[macro.units_size_drone_attackdrone_impulse_mk1_macro, macro.units_size_drone_attackdrone_impulse_mk2_macro, macro.units_size_drone_attackdrone_plasma_mk1_macro, macro.units_size_drone_attackdrone_plasma_mk2_macro, macro.units_size_drone_missiledrone_dumbfire_mk1_macro, macro.units_size_drone_missiledrone_dumbfire_mk2_macro]"/>
      <set_value name="$amountlist" exact="[$launchercapacity * 0.4, $launchercapacity * 0.1, $launchercapacity * 0.2, $launchercapacity * 0.1, $launchercapacity * 0.1, $launchercapacity * 0.1]"/>
      <set_value name="$warelist" exact="[drp_interceptor_mk1, drp_interceptor_mk2, drp_intrepid_mk1, drp_intrepid_mk2, drp_overrun_mk1, drp_overrun_mk2]"/>

      <do_if value="($launchercapacity gt 0) and ($macrolist.count gt 0)">
        <do_if value="$object.units.count lt ($launchercapacity)">
        <!--<do_if value="$object.ammostorage.missile.count lt ($launchercapacity + $object.ammostorage.missile.basecapacity)">-->

          <!-- now figure out how to distribute the amounts -->
          <do_all exact="$warelist.count" counter="$i">
            <set_value name="$ware" exact="$warelist.{$i}" />
            <set_value name="$macro" exact="$macrolist.{$i}" />

            <set_value name="$capacityfactor" exact="($amountlist.{$i})f / $launchercapacity" />

            <!-- w.e: when is this ever set?  Isn't automated ammo purchases a boolean? -->
            <!--<do_if value="$configentity.isoperational">
              <do_if value="$configentity.$config_missilestorage_macros? and $configentity.$config_missilestorage_amounts?">
                <set_value name="$macroindex" exact="@$configentity.$config_missilestorage_macros.indexof.{$macro}" />
                <do_if value="$macroindex gt 0">
                  <set_value name="$capacityfactor" exact="@$configentity.$config_missilestorage_amounts.{$macroindex}" />
                </do_if>
                <do_else>
                  <set_value name="$capacityfactor" exact="1.0f / $macrolist.count" />
                </do_else>
              </do_if>
            </do_if>-->
            <set_value name="$wantamount" exact="$capacityfactor * ($launchercapacity)" />
            <!--<set_value name="$wantamount" exact="$capacityfactor * ($object.ammostorage.missile.basecapacity + $launchercapacity)" />-->
            <do_if value="$wantamount gt 0">
              <get_ware_reservation result="$reservedamount" virtual="true" ware="$ware" mission="false" object="$object" />
              <set_value name="$haveamount" exact="$object.units.{unitcategory.defence}.count" />
              <!--<set_value name="$haveamount" exact="$object.ammostorage.{$macro}.count" />-->
              <set_value name="$needamount" exact="$wantamount - $haveamount - $reservedamount" />
              <set_value name="$fillpercent" exact="($haveamount)f / $wantamount" />
              <do_if value="$fillpercent gt 1.0f">
                <set_value name="$fillpercent" exact="1.0f" />
              </do_if>
              <do_if value="$fillpercent lt 0.7f">
                <!-- use the average price as the lower end to make sure the offers are attractive -->
                <set_value name="$price" exact="$ware.averageprice + (($ware.maxprice - $ware.averageprice)f * (1.0f - $fillpercent))" />
                <debug_text text="'need %1 %2 for %3Cr each, fillpercent: %4'.[$needamount, $ware.name, $price/1Cr, $fillpercent]" chance="$debugchance" />

                <append_to_list name="$order_macrolist" exact="$macro" />
                <append_to_list name="$order_warelist" exact="$ware" />
                <append_to_list name="$order_pricelist" exact="$price" />
                <append_to_list name="$order_amountlist" exact="$needamount" />
              </do_if>
            </do_if>
          </do_all>
        </do_if>

      </do_if>

      <return value="$order_macrolist.count gt 0">
        <retval name="macros" value="$order_macrolist" />
        <retval name="wares" value="$order_warelist" />
        <retval name="prices" value="$order_pricelist" />
        <retval name="amounts" value="$order_amountlist" />
        <retval name="raw_wares" value="$warelist" />
      </return>

    </actions>
  </attention>
</aiscript>

Posted: Sun, 2. Aug 15, 19:28
by w.evans
Progress of sorts. This generates a logical order list:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<aiscript name="MICT.lib.units.combat" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="aiscripts.xsd" priority="1">
  <params>
    <param name="object" default="null" />
    <param name="configentity" default="null" />
    <param name="debugchance" default="0" />
  </params>
  <attention min="unknown">
    <actions>

      <do_if value="not $object.exists">
        <set_value name="$object" exact="this.defensible" />
      </do_if>

      <show_notification caption="'=== MICT Drone Project ==='" details="'%1 preparing combat drone order.'.[$object.knownname]" queued="false" priority="8"/>
      <write_to_logbook category="tips" text="'%1 preparing combat drone order.'.[$object.knownname]"/>

      <create_list name="$order_macrolist" />
      <create_list name="$order_warelist" />
      <create_list name="$order_pricelist" />
      <create_list name="$order_amountlist" />

      <set_value name="$launchercapacity" exact="$object.units.maxcount - 100"/>
      <set_value name="$macrolist" exact="[macro.units_size_drone_attackdrone_impulse_mk1_macro, macro.units_size_drone_attackdrone_impulse_mk2_macro, macro.units_size_drone_attackdrone_plasma_mk1_macro, macro.units_size_drone_attackdrone_plasma_mk2_macro, macro.units_size_drone_missiledrone_dumbfire_mk1_macro, macro.units_size_drone_missiledrone_dumbfire_mk2_macro]"/>
      <set_value name="$amountlist" exact="[$launchercapacity * 0.4, $launchercapacity * 0.1, $launchercapacity * 0.2, $launchercapacity * 0.1, $launchercapacity * 0.1, $launchercapacity * 0.1]"/>
      <set_value name="$warelist" exact="[ware.drp_interceptor_mk1, ware.drp_interceptor_mk2, ware.drp_intrepid_mk1, ware.drp_intrepid_mk2, ware.drp_overrun_mk1, ware.drp_overrun_mk2]"/>

      <do_if value="($launchercapacity gt 0) and ($macrolist.count gt 0)">
        <do_if value="$object.units.count lt ($launchercapacity)">

          <!-- now figure out how to distribute the amounts -->
          <do_all exact="$warelist.count" counter="$i">
            <set_value name="$ware" exact="$warelist.{$i}" />
            <set_value name="$macro" exact="$macrolist.{$i}" />

            <set_value name="$capacityfactor" exact="($amountlist.{$i})f / $launchercapacity" />

            <!-- w.e: when is this ever set?  Isn't automated ammo purchases a boolean? -->
            <!--<do_if value="$configentity.isoperational">
              <do_if value="$configentity.$config_missilestorage_macros? and $configentity.$config_missilestorage_amounts?">
                <set_value name="$macroindex" exact="@$configentity.$config_missilestorage_macros.indexof.{$macro}" />
                <do_if value="$macroindex gt 0">
                  <set_value name="$capacityfactor" exact="@$configentity.$config_missilestorage_amounts.{$macroindex}" />
                </do_if>
                <do_else>
                  <set_value name="$capacityfactor" exact="1.0f / $macrolist.count" />
                </do_else>
              </do_if>
            </do_if>-->
            <set_value name="$wantamount" exact="$capacityfactor * ($launchercapacity)" />
            <do_if value="$wantamount gt 0">
              <get_ware_reservation result="$reservedamount" virtual="true" ware="$ware" mission="false" object="$object" />
              <set_value name="$haveamount" exact="$object.units.{unitcategory.defence}.count" />
              <set_value name="$needamount" exact="$wantamount - $haveamount - $reservedamount" />
              <set_value name="$fillpercent" exact="($haveamount)f / $wantamount" />
              <do_if value="$fillpercent gt 1.0f">
                <set_value name="$fillpercent" exact="1.0f" />
              </do_if>
              <do_if value="$fillpercent lt 0.7f">
                <!-- use the average price as the lower end to make sure the offers are attractive -->
                <set_value name="$price" exact="$ware.averageprice + (($ware.maxprice - $ware.averageprice)f * (1.0f - $fillpercent))" />
                <debug_text text="'need %1 %2 for %3Cr each, fillpercent: %4'.[$needamount, $ware.name, $price/1Cr, $fillpercent]" chance="$debugchance" />

                <append_to_list name="$order_macrolist" exact="$macro" />
                <append_to_list name="$order_warelist" exact="$ware" />
                <append_to_list name="$order_pricelist" exact="$price" />
                <append_to_list name="$order_amountlist" exact="$needamount" />

                <show_notification caption="'=== MICT Drone Project ==='" details="'%1 placed order for \n %2 units of %3 \n at %4Cr per unit.'.[$object.knownname, $needamount, $ware, $price / 100]" queued="false" priority="8"/>
                <write_to_logbook category="tips" text="'%1 placed order for \n %2 units of %3 \n at %4Cr per unit.'.[$object.knownname, $needamount, $ware, $price / 100]"/>

              </do_if>
            </do_if>
          </do_all>
        </do_if>

      </do_if>

      <return value="$order_macrolist.count gt 0">
        <retval name="macros" value="$order_macrolist" />
        <retval name="wares" value="$order_warelist" />
        <retval name="prices" value="$order_pricelist" />
        <retval name="amounts" value="$order_amountlist" />
        <retval name="raw_wares" value="$warelist" />
      </return>

    </actions>
  </attention>
</aiscript>
But the stations don't actually generate orders. Checked, and it seems like they aren't generating orders for missiles either?

Posted: Sun, 2. Aug 15, 20:34
by w.evans
Woohoo! Working! Re-traced the script flow for station-based ammo, and I missed a step: stations run lib.ammo.station, and that runs lib.ammo.missiles. Order list is generated in lib.ammo.missiles -> then order lists are converted to orders in lib.ammo.station.

Will probably cause a drone shortage, but there are pros and cons to that. Will test a bit more before considering release.

Posted: Sun, 2. Aug 15, 23:10
by w.evans
Spoke too soon. Player-owned stations are making trade orders for combat drones, but NPC stations aren't. They successfully fire <create_trade_offer, but it doesn't actually appear in the trade menu. :headbang:

Posted: Mon, 3. Aug 15, 00:50
by w.evans
Thinking aloud here. If anyone has any insight, don't shy away from chiming in.

Decided to Keep It Simple, Stupid, and came up with this:

Code: Select all

<do_if value="this.station.units.count lt this.station.units.maxcount">
	<set_value name="$MICT_StDrTradeFreeCapacity" exact="this.station.units.maxcount - this.station.units.count"/>
	<set_value name="$MICT_StDrTradeWare" exact="ware.drp_interceptor_mk1"/>
	<set_value name="$MICT_StDrTradePrice" exact="ware.drp_interceptor_mk1.averageprice"/>

	<create_trade_offer amount="$MICT_StDrTradeFreeCapacity" buyer="this.station" object="this.station" name="$MICT_StDrTrade" ware="$MICT_StDrTradeWare" price="$MICT_StDrTradePrice" unbundle="true" playeronly="false" />

	<show_notification caption="'=== MICT Drone Project ==='" details="'%1 placed order for \n %2 units of %3 \n at %4Cr per unit.'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]" queued="false" priority="8"/>
	<write_to_logbook category="tips" text="'%1 placed order for \n %2 units of %3 \n at %4Cr per unit.'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]"/>
</do_if>
Works, sort of. All of the player-owned stations place orders on the market for interceptor mk1s, and NPCs trade with them, and everyone's happy.

HOWEVER, NPC stations do not place orders. Could verify that it fires: <create_trade_offer ... /> is run by NPC-owned stations, but it doesn't generate actual trade orders.

Now, adding <add_tradeware ware="$MICT_StDrTradeWare" object="this.station" allowbuy="true"/> DOES result in NPCs generating a trade order for that ware, however they do not then equip the drones that they buy! Rather, <add_tradeware ... /> appears to be a general-purpose command to get stations to trade in that ware with amount governed by how much storage they have, and price governed by supply and demand -- itself interesting, but not what I'm trying to do at this time.

Posted: Mon, 3. Aug 15, 01:58
by w.evans
So far, so good. Clumsy, though.

Code: Select all

<do_if value="(this.station.trueowner != faction.player) or @this.$config_unitstorage_automatic">
	<do_if value="this.station.units.count lt this.station.units.maxcount">
		<do_if value="this.station.cargo.{ware.drp_interceptor_mk1}.count gt 0">

			<add_units object="this.station" macro="macro.units_size_drone_attackdrone_impulse_mk1_macro" exact="this.station.cargo.{ware.drp_interceptor_mk1}.count"/>
			<remove_cargo object="this.station" ware="ware.drp_interceptor_mk1" exact="this.station.cargo.{ware.drp_interceptor_mk1}.count"/>

			<show_notification caption="'=== MICT Drone Project ==='" details="'%1 \n has acquired %2 drones. \n Taking out of storage.'.[this.station.knownname, this.station.cargo.{ware.drp_interceptor_mk1}.count]" queued="false" priority="9"/>
			<write_to_logbook category="tips" text="'%1 \n has acquired %2 drones. \n Taking out of storage.'.[this.station.knownname, this.station.cargo.{ware.drp_interceptor_mk1}.count]"/>
		</do_if>

		<set_value name="$MICT_StDrTradeFreeCapacity" exact="this.station.units.maxcount - this.station.units.count"/>
		<set_value name="$MICT_StDrTradeWare" exact="ware.drp_interceptor_mk1"/>
		<set_value name="$MICT_StDrTradePrice" exact="ware.drp_interceptor_mk1.averageprice"/>

		<add_tradeware ware="$MICT_StDrTradeWare" object="this.station" allowbuy="true"/>

		<find_buy_offer buyer="this.station" wares="$MICT_StDrTradeWare" result="$MICT_StDrTradeOfferMult" excludeempty="false" multiple="true"/>

		<show_notification caption="'=== MICT Drone Project ==='" details="'%1 \n NODE 1'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]" queued="false" priority="1"/>
		<write_to_logbook category="tips" text="'%1 \n NODE 1'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]"/>

		<do_if value="$MICT_StDrTradeOfferMult?">
			<do_all exact="$MICT_StDrTradeOfferMult.count" counter="$i">
				<set_value name="$MICT_StDrTradeOffer" exact="$MICT_StDrTradeOfferMult.{$i}"/>

				<update_trade trade="$MICT_StDrTradeOffer" amount="$MICT_StDrTradeFreeCapacity" desiredamount="$MICT_StDrTradeFreeCapacity" unbundle="true"/>

				<show_notification caption="'=== MICT Drone Project ==='" details="'%1 \n NODE 2'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]" queued="false" priority="1"/>
				<write_to_logbook category="tips" text="'%1 \n NODE 2'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]"/>
			</do_all>
		</do_if>
		<do_else>
			<create_trade_offer amount="$MICT_StDrTradeFreeCapacity" buyer="this.station" object="this.station" name="$MICT_StDrTrade" ware="$MICT_StDrTradeWare" price="$MICT_StDrTradePrice" unbundle="true" playeronly="false" />

			<show_notification caption="'=== MICT Drone Project ==='" details="'%1 \n NODE 3'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]" queued="false" priority="1"/>
			<write_to_logbook category="tips" text="'%1 \n NODE 3'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]"/>
		</do_else>

		<show_notification caption="'=== MICT Drone Project ==='" details="'%1 placed an order for \n %2 units of %3 \n at %4Cr per unit.'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]" queued="false" priority="1"/>
		<write_to_logbook category="tips" text="'%1 placed an order for \n %2 units of %3 \n at %4Cr per unit.'.[this.station.knownname, $MICT_StDrTradeFreeCapacity, $MICT_StDrTradeWare, $MICT_StDrTradePrice / 100]"/>
	</do_if>
</do_if>

Posted: Mon, 3. Aug 15, 06:48
by UniTrader
w.evans wrote: Works, sort of. All of the player-owned stations place orders on the market for interceptor mk1s, and NPCs trade with them, and everyone's happy.

HOWEVER, NPC stations do not place orders. Could verify that it fires: <create_trade_offer ... /> is run by NPC-owned stations, but it doesn't generate actual trade orders.

Now, adding <add_tradeware ware="$MICT_StDrTradeWare" object="this.station" allowbuy="true"/> DOES result in NPCs generating a trade order for that ware, however they do not then equip the drones that they buy! Rather, <add_tradeware ... /> appears to be a general-purpose command to get stations to trade in that ware with amount governed by how much storage they have, and price governed by supply and demand -- itself interesting, but not what I'm trying to do at this time.
thx for this insight - helps me to resolve the issue that my manager tries to stock 131K fuel cells which is far more than necessary - will add a new subscription to generate /update offers with better-suited amounts instead of trying to change the $station. cargo.{$ware}.wanted amount.. Thats what you would need but no idea how to achieve this, I doubt a <set_value />would work here

Posted: Mon, 3. Aug 15, 10:39
by w.evans
Glad to help! There is a delay between <add_tradeware and <update_trade, but since they usually need a lot of drones, especially when drone capacity is increased, there's a very small chance that a station will get more drones than it needs; and I think I have to add a condition for <add_tradeware because it really only has to be done once.

Next to add multiple drone types. Setting them to particular proportions is ok, but would be better if the player can set them somehow.