How to calculate the consumption of a ware for a station?

The place to discuss scripting and game modifications for X4: Foundations.

Moderators: Moderators for English X Forum, Scripting / Modding Moderators

Post Reply
thijso
Posts: 89
Joined: Thu, 2. Jul 20, 23:24

How to calculate the consumption of a ware for a station?

Post by thijso » Fri, 4. Sep 20, 19:03

Looking through the xml files of the game, I've managed to come up with this:

Code: Select all

<find_object_component groupname="$stationmodules" object="$srcStation" checkoperational="true" class="class.module" multiple="true"/>
<debug_to_file chance="$debugchance" name="$debugFileName" directory="'DumbMule'"
               text="' %s modules on %s %s'.[$stationmodules.count, $srcStation.idcode, $srcStation.knownname]" />

<do_all exact="$stationmodules.count" counter="$ModuleCounter">
    <debug_to_file chance="$debugchance" name="$debugFileName" directory="'DumbMule'"
                   text="' %s module: %s : %s'.[$stationmodules.{$ModuleCounter}, $stationmodules.{$ModuleCounter}.name, $stationmodules.{$ModuleCounter}.class]" />
    <debug_to_file chance="$debugchance" name="$debugFileName" directory="'DumbMule'"
                   text="' %s : %s : %s'.[$stationmodules.{$ModuleCounter}, $stationmodules.{$ModuleCounter}.productionvolume, $stationmodules.{$ModuleCounter}.consumptionvolume]" />
</do_all>
This kinda works, except for the last part. I get something like this in my logs:

Code: Select all

 29 modules on MGC-302 Nopileos' Fortune II Refined Goods 01
 0x3965f4a module: 3M6S Standard Dock Area : dockarea
 0x3965f4a : null : null
 0x408e912 module: Refined Metal Production : production
 0x408e912 : null : null
 0x38d3765 module: Graphene Production : production
 0x38d3765 : null : null
 0x48c4627 module: Antimatter Cell Production : production
 0x48c4627 : null : null
 0x3065057 module: Silicon Wafer Production : production
 0x3065057 : null : null
 0x303b7f5 module: Superfluid Coolant Production : production
 0x303b7f5 : null : null
 0x2943196 module: Energy Cell Production : production
 0x2943196 : null : null
 0x3040813 module: Refined Metal Production : production
 0x3040813 : null : null
 0x3068ddb module: Silicon Wafer Production : production
 0x3068ddb : null : null
 0x304eb53 module: Refined Metal Production : production
 0x304eb53 : null : null
 0x3075abb module: Teladi L Solid Storage : storage
 0x3075abb : null : null
 0x40c5f22 module: Teladi L Liquid Storage : storage
 0x40c5f22 : null : null
 0x38bb1da module: Teladi L Container Storage : storage
 0x38bb1da : null : null
 0x40d08a7 module: Argon L Habitat : habitation
 0x40d08a7 : null : null
 0x38cfcd5 module: Argon Base Connection Structure 01 : connectionmodule
 0x38cfcd5 : null : null
 0x3141417 module: Argon Cross Connection Structure 01 : connectionmodule
 0x3141417 : null : null
 0x38ccb40 module: Argon Base Connection Structure 01 : connectionmodule
 0x38ccb40 : null : null
 0x4061c38 module: Argon Cross Connection Structure 01 : connectionmodule
 0x4061c38 : null : null
 0x40626cb module: Argon Cross Connection Structure 01 : connectionmodule
 0x40626cb : null : null
 0x40619a4 module: Argon Cross Connection Structure 01 : connectionmodule
 0x40619a4 : null : null
 0x4061b36 module: Argon Base Connection Structure 01 : connectionmodule
 0x4061b36 : null : null
 0x4061b3b module: Argon Base Connection Structure 01 : connectionmodule
 0x4061b3b : null : null
 0x4061ad8 module: Argon Cross Connection Structure 01 : connectionmodule
 0x4061ad8 : null : null
 0x38e4642 module: Argon Base Connection Structure 01 : connectionmodule
 0x38e4642 : null : null
 0x38ccb26 module: Argon Cross Connection Structure 01 : connectionmodule
 0x38ccb26 : null : null
 0x4061add module: Argon Base Connection Structure 01 : connectionmodule
 0x4061add : null : null
 0x388ba66 module: Argon Cross Connection Structure 01 : connectionmodule
 0x388ba66 : null : null
 0x3141449 module: Argon Base Connection Structure 01 : connectionmodule
 0x3141449 : null : null
 0x38e8e51 module: Argon Cross Connection Structure 01 : connectionmodule
 0x38e8e51 : null : null
As you see, the productionvolume and consumptionvolume are always null.

I expected them to work, as I see the following in the game files (finalisestations.xml):

Code: Select all

<!-- Calculate the throughput of the station (volume of wares being produced and consumed on a station) -->
<set_value name="$ProductionVolume" exact="0" />
<set_value name="$ConsumptionVolume" exact="0" />
<do_all exact="$PlannedModules.count" counter="$ModuleCounter">
  <do_if value="$PlannedModules.{$ModuleCounter}.isclass.production">
    <set_value name="$ProductionVolume" operation="add" exact="$PlannedModules.{$ModuleCounter}.productionvolume" />
    <set_value name="$ConsumptionVolume" operation="add" exact="$PlannedModules.{$ModuleCounter}.consumptionvolume" />
  </do_if>
</do_all>
So it seems those $PlannedModules are not the same as the modules I get. I'm stumped...

Any help greatly appreciated!

thijso
Posts: 89
Joined: Thu, 2. Jul 20, 23:24

Re: How to calculate the consumption of a ware for a station?

Post by thijso » Fri, 4. Sep 20, 22:50

So, I've realized that I should just be able to hardcode the consumption of each type of module, but I'd rather not do that.

Am I wrong in thinking it should be possible to discover this through the code?

thijso
Posts: 89
Joined: Thu, 2. Jul 20, 23:24

Re: How to calculate the consumption of a ware for a station?

Post by thijso » Mon, 7. Sep 20, 09:27

So I ended up hardcoding the consumption values. I used lists as there I can just use plain old strings. It's clunky, but it works. And since the calculations are restricted to those instances where a ware is also a resource (not that often I find in my use cases), I don't think the impact is too bad. What I've got now is:

Code: Select all

      <!-- predefine some things -->
      <set_value name="$ProdConsumptions" exact="['Spacefuel Production',['energycells',300,'water',750,'wheat',600],'Silicon Wafer Production',['energycells',1800,'silicon',4800],'Maja Snail Production',['energycells',320,'water',800],'Spaceweed Production',['energycells',840,'spices',240,'swampplant',720],'Refined Metal Production',['energycells',2160,'ore',5760],'Plasma Conductor Production',['energycells',240,'graphene',384,'superfluidcoolant',560],'Smart Chip Production',['energycells',300,'siliconwafers',120],'Scanning Array Production',['energycells',360,'refinedmetals',600,'siliconwafers',360],'Sunrise Flower Production',['energycells',360,'water',960],'Antimatter Cell Production',['energycells',3000,'hydrogen',9600],'Teladianium Production',['energycells',1350,'ore',8400],'Meat Production',['energycells',320,'water',800],'Soja Bean Production',['energycells',360,'water',960],'Weapon Component Production',['energycells',120,'hullparts',40,'plasmaconductors',60],'Superfluid Coolant Production',['energycells',900,'helium',4800],'Turret Component Production',['energycells',120,'microchips',40,'quantumtubes',40,'scanningarrays',20],'Antimatter Converter Production',['advancedcomposites',240,'energycells',960,'microchips',360],'Shield Component Production',['energycells',210,'plasmaconductors',60,'quantumtubes',60],'Spice Production',['energycells',240,'water',480],'Quantum Tube Production',['energycells',200,'graphene',580,'superfluidcoolant',150],'Advanced Composite Production',['energycells',600,'graphene',960,'refinedmetals',960],'Microchip Production',['energycells',300,'siliconwafers',1200],'Swamp Plant Production',['energycells',320,'water',800],'Medical Supply Production',['energycells',480,'spices',360,'water',720,'wheat',264],'Engine Part Production',['antimattercells',320,'energycells',240,'refinedmetals',384],'Chelt Production',['energycells',400,'water',960],'Graphene Production',['energycells',1200,'methane',4800],'Missile Component Production',['advancedcomposites',8,'energycells',80,'hullparts',8],'Field Coil Production',['energycells',360,'plasmaconductors',240,'quantumtubes',258],'Water Production',['energycells',1800,'ice',9600],'Scruffin Production',['energycells',360,'water',960],'Maja Dust Production',['energycells',240,'majasnails',720,'spices',360],'Food Ration Production',['energycells',600,'meat',600,'spices',300,'wheat',600],'Claytronics Production',['antimattercells',400,'energycells',560,'microchips',640,'quantumtubes',400],'Hull Part Production',['energycells',320,'graphene',160,'refinedmetals',1120],'Drone Component Production',['energycells',180,'engineparts',60,'hullparts',60,'microchips',60,'scanningarrays',120],'Nostrop Oil Production',['energycells',480,'spices',240,'sunriseflowers',480,'water',480],'Wheat Production',['energycells',360,'water',960],'Advanced Electronics Production',['energycells',300,'microchips',220,'quantumtubes',100],'Soja Husk Production',['energycells',480,'majasnails',480,'sojabeans',480,'spices',240]]" />
      <set_value name="$HabConsumptions" exact="['Paranid L Dome',['sojahusk',715,'medicalsupplies',675],'Paranid S Dome',['sojahusk',239,'medicalsupplies',225],'Teladi L Biome',['nostropoil',571,'medicalsupplies',676],'Teladi S Biome',['nostropoil',143,'medicalsupplies',169],'Split L Parlour',['cheltmeat',251,'scruffinfruits',351,'medicalsupplies',676],'Split S Parlour',['cheltmeat',63,'scruffinfruits',88,'medicalsupplies',169],'Argon M Habitat',['foodrations',563,'medicalsupplies',338],'Argon S Habitat',['foodrations',282,'medicalsupplies',169],'Argon L Habitat',['foodrations',1126,'medicalsupplies',676],'Split M Parlour',['cheltmeat',126,'scruffinfruits',176,'medicalsupplies',338],'Teladi M Biome',['nostropoil',286,'medicalsupplies',338],'Paranid M Dome',['sojahusk',477,'medicalsupplies',450]]" />
Then later if the ware is a resource, I check all the modules at the station and add up the amounts each module needs of the resource per hour. Then, using the parameter that you have to set at the start, it makes sure the mule always leaves that amount of resources at the station.

Code: Select all

<!-- we shouldn't empty out resources -->
<do_if value="$srcResources.indexof.{$ware} gt 0">

  <set_value name="$stationmodules" exact="[]" />
  <find_object_component groupname="$stationmodules" object="$srcStation" checkoperational="true" class="class.module" multiple="true"/>

  <set_value name="$ware_consumption" exact="0" />

  <do_all exact="$stationmodules.count" counter="$ModuleCounter">
    <do_if value="$stationmodules.{$ModuleCounter}.isclass.habitation">

      <set_value name="$modulename" exact="$stationmodules.{$ModuleCounter}.name" />
      <set_value name="$mod_index" exact="$HabConsumptions.indexof.{$modulename}" />
      <do_if value="$mod_index gt 0">
        <set_value name="$ware_name" exact="$ware.id" />
        <set_value name="$ware_list" exact="$HabConsumptions.{$mod_index+1}" />
        <set_value name="$ware_idx" exact="$ware_list.indexof.{$ware_name}" />

        <do_if value="$ware_idx gt 0">
          <set_value name="$ware_consumption" operation="add" exact="$ware_list.{$ware_idx+1}" />
        </do_if>
      </do_if>
    </do_if>
    <do_if value="$stationmodules.{$ModuleCounter}.isclass.production">

      <set_value name="$modulename" exact="$stationmodules.{$ModuleCounter}.name" />
      <set_value name="$mod_index" exact="$ProdConsumptions.indexof.{$modulename}" />
      <do_if value="$mod_index gt 0">
        <set_value name="$ware_name" exact="$ware.id" />
        <set_value name="$ware_list" exact="$ProdConsumptions.{$mod_index+1}" />
        <set_value name="$ware_idx" exact="$ware_list.indexof.{$ware_name}" />

        <do_if value="$ware_idx gt 0">
          <set_value name="$ware_consumption" operation="add" exact="$ware_list.{$ware_idx+1}" />
        </do_if>
      </do_if>
    </do_if>
  </do_all>

  <debug_to_file chance="$debugchance" name="$debugFileName" directory="'DumbMule'"
                 text="' total consumption = %s'.[$ware_consumption]" />

  <set_value name="$maxToGet"
             exact="$srcStation.cargo.{$ware}.count - ($ware_consumption * $minResourceFactor)" />
  <debug_to_file chance="$debugchance" name="$debugFileName" directory="'DumbMule'"
                 text="'resource at station: getting %1 of %2 (requested was %3)'.[$maxToGet,$srcStation.cargo.{$ware}.count,$cargoHauled]" />

  <remove_value name="$ware_consumption" />
  <remove_value name="$stationmodules" />

  <do_if value="$maxToGet le 0">
    <!-- not enough available for trade, skip -->
    <continue />
  </do_if>

  <set_value name="$cargoHauled" exact="[$cargoHauled,$maxToGet].min" />
</do_if>
So that works, but if anyone has a idea how to do this better (the list traversal is a little wasteful) I'm open to suggestions...

kuertee
EGOSOFT
EGOSOFT
Posts: 789
Joined: Sun, 14. Dec 03, 13:05
x4

Re: How to calculate the consumption of a ware for a station?

Post by kuertee » Mon, 7. Sep 20, 10:30

What happens with "$stationmodules.{$ModuleCounter}.name" when the game is played with the German language?
I mean in regards to your lists.
Will it's data be found regardless of language?
I don't know. It may be found. It may not.
(Just thinking out loud.)
Mods: RPG: Reputations and Professions, Social Standings and Citizenships, Crime has Consequences, Alternatives to Death. Missions/NPCs: Emergent Missions, NPC Reactions, Mod Parts Trader, High-sec Rooms are Locked, Hacking Outcomes, More Generic Missions, Waypoint Fields for Deployment. Others: Auto-cam, Friendly Fire Tweaks, Teleport From Transporter Room, Wear and Tear. QoL: Trade Analytics, Loot Mining, Ship Scanner, Signal Leak Hunter, Station Scanner, Surface Element Targeting, etc.

thijso
Posts: 89
Joined: Thu, 2. Jul 20, 23:24

Re: How to calculate the consumption of a ware for a station?

Post by thijso » Mon, 7. Sep 20, 10:51

Yeah, that's gonna break it. I think.
That's why I was looking for a 'standard' way to do it. The information is there in the logical overview of the station, so why can't I access that data direct?

kuertee
EGOSOFT
EGOSOFT
Posts: 789
Joined: Sun, 14. Dec 03, 13:05
x4

Re: How to calculate the consumption of a ware for a station?

Post by kuertee » Mon, 7. Sep 20, 17:29

did you look if they are available as a property of a station or module as listed in the scriptproperties.xml file in the library folder?
(unfortunately, my games drive died JUST last night, so I can't check and can't give you an exact answer.)
Mods: RPG: Reputations and Professions, Social Standings and Citizenships, Crime has Consequences, Alternatives to Death. Missions/NPCs: Emergent Missions, NPC Reactions, Mod Parts Trader, High-sec Rooms are Locked, Hacking Outcomes, More Generic Missions, Waypoint Fields for Deployment. Others: Auto-cam, Friendly Fire Tweaks, Teleport From Transporter Room, Wear and Tear. QoL: Trade Analytics, Loot Mining, Ship Scanner, Signal Leak Hunter, Station Scanner, Surface Element Targeting, etc.

thijso
Posts: 89
Joined: Thu, 2. Jul 20, 23:24

Re: How to calculate the consumption of a ware for a station?

Post by thijso » Tue, 8. Sep 20, 10:03

The two params I mention in the first post (productionvolume and consumptionvolume) are listed as properties of macro with base type dbdata.

I also see production as a type of module with products and resources properties.

I have tried to get values for all of these, but no luck. Maybe I'm doing it wrong.

kuertee
EGOSOFT
EGOSOFT
Posts: 789
Joined: Sun, 14. Dec 03, 13:05
x4

Re: How to calculate the consumption of a ware for a station?

Post by kuertee » Tue, 8. Sep 20, 13:57

thijso wrote:
Tue, 8. Sep 20, 10:03
The two params I mention in the first post (productionvolume and consumptionvolume) are listed as properties of macro with base type dbdata.

I also see production as a type of module with products and resources properties.

I have tried to get values for all of these, but no luck. Maybe I'm doing it wrong.
What I do when I find a property that could be what I need but don’t know how to use, I do a regex search for how it is used in the Mission Director (md) folder.
Mods: RPG: Reputations and Professions, Social Standings and Citizenships, Crime has Consequences, Alternatives to Death. Missions/NPCs: Emergent Missions, NPC Reactions, Mod Parts Trader, High-sec Rooms are Locked, Hacking Outcomes, More Generic Missions, Waypoint Fields for Deployment. Others: Auto-cam, Friendly Fire Tweaks, Teleport From Transporter Room, Wear and Tear. QoL: Trade Analytics, Loot Mining, Ship Scanner, Signal Leak Hunter, Station Scanner, Surface Element Targeting, etc.

Post Reply

Return to “X4: Foundations - Scripts and Modding”