[PROBLEM] Mass Traffic Blues

The place to discuss scripting and game modifications for X Rebirth.

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

w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

[PROBLEM] Mass Traffic Blues

Post by w.evans »

Hey everyone,

Has anyone had any experience playing with ship-based mass traffic? Posting this here in case someone might have some insight before I give up on it.

On and off for the past couple of weeks, I've been trying to get ship-based engineers to use their Construction URVs to repair other ships. The repair part in itself works. However, the bit about using Construction URVs is problematic.

...
PROBLEM: The command that actually launches the welder drones in engineer.ai is:

Code: Select all

<launch_repair_drones object="$Defensible" target="$Defensible" components="$MassTrafficTargets" result="$networkid"/>
Defining a different ship as "$Defensible" and changing that line to:

Code: Select all

<launch_repair_drones object="this.defensible" target="$Defensible" components="$MassTrafficTargets" result="$networkid"/>
works. Welder drones are launched from this.defensible and form a mass traffic network around $Defensible. HOWEVER, there appears to be no way to manipulate the resulting mass traffic network.

An engineer repairing his/her own ship has the following variables saved in the save file:
Engineer repairing own ship wrote:<entity id="[0x1ac7]">
<script id="36" name="engineer.ai" version="8" label="checkforrepair" time="874920.199" index="6">
<command type="repair"/>
<commandaction type="repairingto">
<param type="component" value="[0x1ad5]"/>
</commandaction>
<vars>
<value name="$BaseRestoreTime" type="time" value="1200"/>
<value name="$CurrentElement" type="component" value="[0x1ad5]"/>
<value name="$Defensible" type="component" value="[0x1abc]"/>
<value name="$FindChance" type="integer" value="5"/>
<value name="$MassTrafficTargets" type="list" value="8145"/>
<value name="$PossibleElements" type="group" value="2166"/>
<value name="$RestoreTime" type="integer"/>
<value name="$addedhullpercentage" type="integer" value="1"/>
<value name="$baserepairrate" type="integer" value="50"/>
<value name="$debugoutputchance" type="integer"/>
<value name="$debugoutputchance2" type="integer"/>
<value name="$hulldamagelimit" type="integer" value="100"/>
<value name="$networkid" type="integer" value="289"/>
<value name="$nextelementcheck" type="integer"/>
<value name="$repairfrequency" type="time" value="10"/>
<value name="$repairrate" type="integer" value="6000"/>
<value name="$repairratefactor" type="integer" value="120"/>
</vars>
</script>
</entity>
Note that $networkid correctly identifies the mass traffic network that the engineer activated.

The resulting mass traffic network is:
networkid 289 wrote:<network id="[0x121]" starttime="581285.92" space="[0x1abc]">
<quotalists>
<quotalist id="[0x122]" starttime="-33" continuous="1" startobject="[0x1abc]" endobject="[0x1abc]">
<quotas>
<quota id="[0x123]" class="repair" amount="24" macro="units_size_xs_welder_drone_macro"/>
</quotas>
</quotalist>
</quotalists>
<involved>
<object id="[0x1abc]"/>
</involved>
<behavior class="repair" numpaths="1" numpoints="13" maxslowroadlength="500"/>
</network>
This network is terminated with the command:

Code: Select all

<end_repair_mass_traffic object="$Defensible"/>
which works because there is only one object involved. Another way to terminate it would be with:

Code: Select all

<end_mass_traffic network="$networkid"/>
which also works because the mass traffic network id is correctly saved in the engineer's variables under variable name "$networkid"

...
Now, if an engineer were to repair a different ship with

Code: Select all

<launch_repair_drones object="this.defensible" target="$Defensible" components="$MassTrafficTargets" result="$networkid"/>
that engineer would have these variables:
Engineer repairing other ship wrote:<entity id="[0x7374]">
<script id="750" name="engineer.ai" version="8" label="checkforrepair" time="875777.472" index="6">
<command type="support">
<param type="component" value="[0x7074]"/>
</command>
<commandaction type="repairingto">
<param type="component" value="[0x709a]"/>
</commandaction>
<vars>
<value name="$BaseRestoreTime" type="time" value="60"/>
<value name="$CurrentElement" type="component" value="[0x709a]"/>
<value name="$Defensible" type="component" value="[0x7074]"/>
<value name="$FindChance" type="integer" value="100"/>
<value name="$MassTrafficTargets" type="list" value="8232"/>
<value name="$PossibleElements" type="group" value="1949"/>
<value name="$RestoreTime" type="integer"/>
<value name="$addedhullpercentage" type="hitpoints" value="50"/>
<value name="$baserepairrate" type="integer" value="50"/>
<value name="$debugoutputchance" type="integer"/>
<value name="$debugoutputchance2" type="integer"/>
<value name="$hulldamagelimit" type="integer" value="90"/>
<value name="$networkid"/>
<value name="$nextelementcheck" type="integer"/>
<value name="$repairfrequency" type="time" value="10"/>
<value name="$repairrate" type="integer" value="2500"/>
<value name="$repairratefactor" type="integer" value="50"/>
<value name="$unitamounts"/>
</vars>
</script>
</entity>
Note how the $networkid variable has NO value.

Oddly, if the ship being repaired has already launched its own welder drones, the network ID of that existing network would show up under $networkid (because of a find_active_repair_mass_traffic command in engineer.ai), but this engineer would nonetheless start a new one, and would fail to record the network ID of the new mass traffic network.

Digging in the save file, managed to find the resulting mass traffic network:
networkid ??? wrote:<network id="[0x20ab]" starttime="875536.135" space="[0x7074]">
<quotalists>
<quotalist id="[0x20ac]" starttime="875536.135" continuous="1" startobject="[0x735f]" endobject="[0x735f]">
<quotas>
<quota id="[0x20ad]" class="repair" amount="10" macro="units_size_xs_welder_drone_macro"/>
</quotas>
</quotalist>
</quotalists>
<involved>
<object id="[0x7074]"/>
<object id="[0x735f]"/>

</involved>
<actuallyinvolved>
<object id="[0x7074]"/>
<object id="[0x735f]"/>
</actuallyinvolved>
<behavior class="repair" numpaths="1" numpoints="14" maxslowroadlength="500">
<weldareas>
<box>
<max x="35.932" y="35.932" z="38.198"/>
<center x="-54.885" y="-14.571" z="-748.738"/>
</box>
<box>
<max x="35.932" y="35.932" z="38.198"/>
<center x="55.003" y="-14.571" z="-748.738"/>
</box>
<box>
<max x="6.801" y="1.712" z="16.306"/>
<center y="-64.016" z="-662.978"/>
</box>
<box>
<max x="15.628" y="3.157" z="7.189"/>
<center x="0.1651" y="28.415" z="-475.475"/>
</box>
<box>
<max x="8.337" y="3.79" z="9.501"/>
<center x="40.188" y="-61.433" z="-650.128"/>
</box>
<box>
<max x="9.501" y="3.79" z="8.337"/>
<center x="42.254" y="32.116" z="-658.531"/>
</box>
<box>
<max x="8.337" y="3.79" z="9.501"/>
<center x="-39.448" y="-61.433" z="-650.128"/>
</box>
<box>
<max x="9.501" y="3.79" z="8.337"/>
<center x="-40.929" y="32.116" z="-657.422"/>
</box>
<box>
<max x="7.189" y="3.157" z="15.628"/>
<center x="-0.2564" y="35.941" z="284.796"/>
</box>
<box>
<max x="9.501" y="3.79" z="8.337"/>
<center x="34.086" y="32.345" z="271.003"/>
</box>
<box>
<max x="9.501" y="3.79" z="8.337"/>
<center x="-34.106" y="32.344" z="272.112"/>
</box>
<box>
<max x="9.501" y="3.79" z="8.337"/>
<center x="34.086" y="32.345" z="297.252"/>
</box>
<box>
<max x="9.501" y="3.79" z="8.337"/>
<center x="-34.106" y="32.344" z="298.361"/>
</box>
<box>
<max x="13.186" y="9.859" z="56.256"/>
<center y="24.653" z="-562.509"/>
</box>
</weldareas>
</behavior>
</network>
I think that the most relevant difference here is that there are two objects defined. If either object is polled to see if it has an identifiable mass traffic network, for purposes of getting the ID, or for terminating the network, the query comes up blank.

Thus

Code: Select all

<end_repair_mass_traffic object="this.defensible"/>
and

Code: Select all

<end_repair_mass_traffic object="$Defensible"/>
both do not work. Invoking both commands together does not work either.

and

Code: Select all

<end_repair_mass_traffic object="[this.defensible, $Defensible]"/>
triggers an error message saying that
debuglog wrote:[=ERROR=] Error in AI script engineer.ai on entity 0x63c4: Evaluated value '[component.{0x63c1L},component.{0x63c1L}]' is not of type component
* Expression: [this.defensible, $Defensible]
If there were a way to poll the resulting network ID, it would be possible to terminate the network using

Code: Select all

<end_mass_traffic ... />
However, haven't yet found one that works. The command:

Code: Select all

find_active_repair_mass_traffic
is supposed to do that, but it is similarly limited by a single object, and does not detect mass traffic networks involving 2 or more objects.
w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans »

Gotcha, I think.

Code: Select all

<find_active_repair_mass_traffic object="$Defensible" result="$networkid"/>
from vanilla engineer.ai was overwriting $networkid. Doesn't look like it's necessary since $networkid is written to the repairing engineer's variables when the mass traffic network is initialized in the first place.

From notes within the xsd files, it appears that that line is a legacy from when $networkid was not written into the save file. At least, there's a warning in common.xsd:
common.xsd wrote:The ID of the mass traffic network - IMPORTANT: this will become invalid if a savegame is loaded
However, both the $networkid saved to the engineer's variables and that corresponding to the actual network do appear to be written to the save file, and do not change when the game is loaded. As such, I think that the offending line can be safely removed. Removal of that line now allows termination of inter-ship repair mass traffic networks via:

Code: Select all

<end_mass_traffic network="$networkid"/>
Yay?
w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans »

Nope.

It works as long as the game isn't saved and reloaded. However, upon game load, all of the entity and mass traffic IDs change, so that the stored value doesn't match the mass traffic ID anymore.
post-load stored network id wrote:<value name="$networkid" type="integer" value="6953"/>
post-load network id wrote:network id="[0x7bf]"
That's why the find_active_repair_mass_traffic command was necessary.

However, as mentioned above, find_active_repair_mass_traffic doesn't work if more than one object is involved in a mass traffic network.

So problem stands. huff.
UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Post by UniTrader »

Are the Welder Drones doing active repairs or do you just launch them for the atmosphere and the repairs themselves are scripted?
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)
w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans »

They're doing active repairs, yes. At least, they form a repair mass traffic network, and repairs appear to be faster with them launched. (Although, just from looking at the code, shouldn't be the case since I already take them into consideration in the calculations, launched or otherwise.)

They're not absolutely necessary for those repairs to be done, however. The part of the mod as released does repairs, but without launching drones.
UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Post by UniTrader »

ok, then using <launch_masstraffic_drone/> and controlling manually where the Drone goes by selecting random positions around the ship to be repaired could do the trick..

or, on the other hand: did you already try to get the MTN from both the repairer and the repaied? asking both for the active repair MTN could result in the two network IDs you search for...
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)
w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans »

UniTrader wrote:or, on the other hand: did you already try to get the MTN from both the repairer and the repaied? asking both for the active repair MTN could result in the two network IDs you search for...
Yup.

Code: Select all

<find_active_repair_mass_traffic object="$Defensible" result="$networkidtarg"/>
and

Code: Select all

<find_active_repair_mass_traffic object="this.defensible" result="$networkidthis"/>
both output null if the network involves more than one object.

Unless there's something I fudged in invoking the command? Or is there a different command that can be used for the purpose?
UniTrader wrote:ok, then using <launch_masstraffic_drone/> and controlling manually where the Drone goes by selecting random positions around the ship to be repaired could do the trick..
If all else fails...
User avatar
Marvin Martian
Posts: 3614
Joined: Sun, 8. Apr 12, 09:40
x4

Post by Marvin Martian »

isn't that "repair-mass-traffic" not always only for show? yes, the repairfactor will be calculated by the dancing drones, but it isn't really necessary, maybe it can also be enought to create a masstraffic on the supporting ship only

Code: Select all

<launch_repair_drones object="this.defensible" target="this.defensible" result="$networkid"/>
in case the repairtarget have his own Engineer it will be create a own repairmasstraffic anyway

to use a masstraffic the object need a navmesh, i don't think smallships will have that

how do the Architect/Shiptrader handle the Welder drones? Here is a similar behavor to this Problem i think
UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Post by UniTrader »

ok, just looked into what commands are available for this, here are my ideas how to approach this in oder of how likely they will succeed:

1. keep one drone on each Object in reserve which you start on <event_savegame_loaded/> (and recall immediately) -> i think this may give the current network ids for both since from my understanding the network is re-used when already existing

2. use the <launch_war_drones/> first to create a masstraffic network with persistent id (at least there is no way to get it via script from what i have seen.. so i assume its either persistent or a bug where a command to retrieve the id is needed), launch the repair drones, recall the war drones



9999. Brute Force: try all possible Network IDs (just kidding :D)
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)
w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans »

Marvin Martian wrote:how do the Architect/Shiptrader handle the Welder drones? Here is a similar behavor to this Problem i think
Tried to find that, but I think it's fully internal.
Marvin Martian wrote:to use a masstraffic the object need a navmesh, i don't think smallships will have that
Good point. Thanks. Will have to write in a condition not to launch drones if the repair target is a small ship. (If can get it to work properly.)
Marvin Martian wrote:maybe it can also be enought to create a masstraffic on the supporting ship only

Code: Select all

<launch_repair_drones object="this.defensible" target="this.defensible" result="$networkid"/>
in case the repairtarget have his own Engineer it will be create a own repairmasstraffic anyway
This does work, but doesn't make visual sense, I think.

The way it works now, even if the target ship doesn't have an engineer but has welder drones equipped, those welder drones will be launched and used to repair. While it's an interesting test case, I doubt that anyone would find themselves in a similar situation, so isn't very useful.

Works well enough, and could leave it at that. But it's really cool when it works. (Only problem now is the mass traffic network IDs changing upon game load.) And the problem's bugging me, because it's soooo close!

...
@Uni, thanks! Will give 1 and 2 a try. Hopefully, won't have to resort to 9999. Can't imagine what the game will do if I tell all engineers everywhere to go through every single possible network ID at the same time!
User avatar
Marvin Martian
Posts: 3614
Joined: Sun, 8. Apr 12, 09:40
x4

Post by Marvin Martian »

Crazy Idea, why not

Code: Select all

<launch_repair_drones object="this.defensible" target="this.defensible" components="$MassTrafficTargets" result="$networkid"/>
masstraffic start and end on the supporting ship, but the $MassTrafficTargets will be on the repairtarget

the only problem is in my opinion the distance between both ships and the low speed of welder drones
w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans »

Marvin Martian wrote:Crazy Idea, why not

Code: Select all

<launch_repair_drones object="this.defensible" target="this.defensible" components="$MassTrafficTargets" result="$networkid"/>
masstraffic start and end on the supporting ship, but the $MassTrafficTargets will be on the repairtarget

the only problem is in my opinion the distance between both ships and the low speed of welder drones
Tried that too. this.defensible would launch welder drones, and those drones would move around this.defensible. I think it plotted positions to the damaged components on $Defensible, but placed them relative to the navmesh of this.defensible.

I'll give it another try, though.

About drone speed, forgot to tell you, probably safer to alter it in \libraries\parameters.xml

Code: Select all

  <masstraffic>
    <objects>
      <deviation>
        <amplitude x="20" y="20" z="20" />
        <period>
          <min x="20" y="30" z="40" />
          <max x="30" y="40" z="50" />
        </period>
        <phase>
          <min x="0" y="0" z="0" />
          <max x="100" y="100" z="100" />
        </phase>
        <factor localhighway="5" superhighway="10" />
      </deviation>
      <speed default="20">
        <tag id="speed_welder_slow" speed="10" />
        <tag id="speed_welder_normal" speed="100" />
        <tag id="speed_highway_entry" speed="100" />
        <tag id="speed_highway_exit" speed="500" />
        <tag id="speed_empty_space" speed="100" />
        <tag id="speed_slow" speed="10" />
        <tag id="speed_fast" speed="40" />
        <tag id="speed_faster" speed="80" />
      </speed>
    </objects>
  </masstraffic>
w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans »

Just checked.

Code: Select all

<launch_repair_drones object="this.defensible" target="this.defensible" components="$MassTrafficTargets" result="$networkid"/>
does indeed make welder drones move relative to this.defensible rather than $Defensible.

@Uni, launch_war_drones has the same problem, but it's kind of worse because, as you said, there's no command to retrieve the resulting network ID. Stands to reason since, as far as I know, this isn't used anywhere in vanilla and is associated with the presently-defunct Assault URVs.

...
In case anyone's interested, here's the work-in-progress (kept lots of commented-out code in the posted sample):

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<diff>
	<!--<add sel="//launch_repair_drones" pos="after">
		<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
			<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 launched. \n Network ID: %3'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $networkid]" queued="false" priority="1"/>
			<write_to_logbook category="tips" text="'%1 drones of \n %2 launched. \n Network ID: %3'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $networkid]"/>
		</do_if>
	</add>-->

	<!-- MICT: accelerated repair rates for testing. -->
	<!--<replace sel="//set_value[@exact='5']/@exact">this.combinedskill</replace>-->
	<!--<replace sel="//set_value[@name='$FindChance'][@exact='5']/@exact">this.combinedskill</replace>-->

	<!--<add sel="//set_object_hull[@object='$Defensible']" pos="after">
		<do_if value="$Defensible != this.defensible and (this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count) gt 0">
			<set_object_hull object="$Defensible" exact="$Defensible.hullpercentage + ($addedhullpercentage * 2)"/>
		</do_if>
	</add>-->

	<replace sel="//set_object_hull[@object='$CurrentElement']/@exact">100</replace>
	<!--<add sel="//set_object_hull[@object='$CurrentElement']" pos="after">
		<do_if value="$Defensible != this.defensible and (this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count) gt 0">
			<set_object_hull object="$CurrentElement" exact="100"/>
		</do_if>
	</add>-->

	<!-- MICT: If this ship doesn't need to be repaired, look for something to repair.
		Valid targets for repair are l-class and xl-class ships and stations.
		Repair most damaged ships/stations first.
		First priority is still the ship/station where the engineer is stationed.

		Problem: At the moment, prioritization is only by hull damage.
			If something has a hull damaged below threshold, but damaged components, that thing won't be repaired by other ships/stations.
			That ship's/station's own engineer should still handle repairs in that case, however.

		Not really a problem, but not very efficient: this.defensible is set as the repair target if:
			this.defensible is not a MICT ship,
			this.defensible has hull damage above threshold or this.defensible is a combat ship,
			there are no valid repair targets within radar range,
			none of the detected potential repair targets are owned by the same faction that owns this.defensible,
			none of the detected potential repair targets actually needs repair.

			Try to figure out a way to simplify?
			Then again, each do_if/do_else block will only be run once, so might be fine.

			Thanks to Marvin Martian for some help with refining this. -->
	<remove sel="//set_value[@name='$Defensible']"/>

	<add sel="//do_if[@value='player.age le @this.$hacked']" pos="before">
	<!--<add sel="//do_if[@value='this.defensible.isclass.station']" pos="before">-->
		<do_if value="@$CurrentElement.exists" negate="true">
		<!--<do_if value="@$MassTrafficTargets.count ge 1" negate="true">-->
			<do_if value="this.defensible.isclass.[class.ship_l, class.ship_xl] and this.combinedskill ge 80 and this.defensible.pilot.combinedskill ge 80 and this.defensible.defencenpc.combinedskill ge 80 and this.defensible.units.{unitcategory.welder}.count gt 0">
				<do_if value="this.defensible.primarypurpose != objectpurpose.fight and this.defensible.hullpercentage ge $hulldamagelimit">
					<find_gravidar_contact name="$MICT_RepairTargets" object="this.defensible" functional="true" multiple="true" checkoperational="true" repairable="true" invulnerable="false" indestructible="false">
						<match_distance object="this.defensible" max="this.defensible.maxradarrange"/>
						<match class="[class.ship_l, class.ship_xl, class.station, class.ship_s, class.ship_m]"/>
						<match_relation faction="this.defensible.trueowner" relation="self" comparison="ge"/>
						<!--<match_relation faction="this.defensible.trueowner" relation="friend" comparison="ge"/>-->
						<match_hull min="$hulldamagelimit" negate="true"/>
						<!--<match repairable="true" invulnerable="false">
							<match_hull min="2"/>
							<match_hull max="$hulldamagelimit - 1"/>
						</match>-->
					</find_gravidar_contact>
					<do_if value="$MICT_RepairTargets.count ge 1">
						<do_all exact="$MICT_RepairTargets.count" counter="$i">
							<!--<do_if value="$MICT_RepairTargets.{$i}.owner == this.defensible.owner">-->
								<do_if value="$MICT_RepairTargets.{$i}.hullpercentage lt @$Defensible.hullpercentage">
									<do_if value="$networkid? and @$Defensible != $MICT_RepairTargets.{$i}">
										<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
											<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 1.1'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]" queued="false" priority="1"/>
											<write_to_logbook category="tips" text="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 1.1'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]"/>
										</do_if>

										<!--<end_repair_mass_traffic object="[this.defensible, $Defensible]"/>-->
										<!--<end_repair_mass_traffic object="this.defensible"/>
										<end_repair_mass_traffic object="$Defensible"/>-->
										<end_mass_traffic network="$networkid"/>
										<remove_value name="$networkid"/>
									</do_if>
									<set_value name="$Defensible" exact="$MICT_RepairTargets.{$i}"/>
									<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
										<show_notification caption="'=== MICT Engineer ==='" details="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 1.1'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count ,this.defensible.distanceto.{$Defensible}]" queued="false" priority="1"/>
										<write_to_logbook category="tips" text="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 1.1'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count ,this.defensible.distanceto.{$Defensible}]" queued="false"/>
									</do_if>
								</do_if>
								<do_elseif value="not $Defensible? and $MICT_RepairTargets.{$i}.hullpercentage lt $hulldamagelimit">
									<do_if value="$networkid? and @$Defensible != $MICT_RepairTargets.{$i}">
										<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
											<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 1.2'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]" queued="false" priority="1"/>
											<write_to_logbook category="tips" text="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 1.2'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]"/>
										</do_if>

										<!--<end_repair_mass_traffic object="[this.defensible, $Defensible]"/>-->
										<!--<end_repair_mass_traffic object="this.defensible"/>
										<end_repair_mass_traffic object="$Defensible"/>-->
										<end_mass_traffic network="$networkid"/>
										<remove_value name="$networkid"/>
									</do_if>
									<set_value name="$Defensible" exact="$MICT_RepairTargets.{$i}"/>
									<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
										<show_notification caption="'=== MICT Engineer ==='" details="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 1.2'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false" priority="1"/>
										<write_to_logbook category="tips" text="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 1.2'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false"/>
									</do_if>
								</do_elseif>
								<do_elseif value="not $Defensible?">
									<do_if value="$networkid? and @$Defensible != this.defensible">
										<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
											<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 1.3'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]" queued="false" priority="1"/>
											<write_to_logbook category="tips" text="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 1.3'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]"/>
										</do_if>

										<!--<end_repair_mass_traffic object="[this.defensible, $Defensible]"/>-->
										<!--<end_repair_mass_traffic object="this.defensible"/>
										<end_repair_mass_traffic object="$Defensible"/>-->
										<end_mass_traffic network="$networkid"/>
										<remove_value name="$networkid"/>
									</do_if>
									<set_value name="$Defensible" exact="this.defensible"/>
									<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
									<!--<do_if value="false">-->
										<show_notification caption="'=== MICT Engineer ==='" details="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 1.3'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false" priority="1"/>
										<write_to_logbook category="tips" text="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 1.3'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false"/>
									</do_if>
								</do_elseif>
								<do_elseif value="$Defensible? and (@$Defensible != this.defensible) and @$Defensible.hullpercentage ge $hulldamagelimit">
									<do_if value="$networkid? and @$Defensible != this.defensible">
										<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
											<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 1.4'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]" queued="false" priority="1"/>
											<write_to_logbook category="tips" text="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 1.4'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]"/>
										</do_if>

										<!--<end_repair_mass_traffic object="[this.defensible, $Defensible]"/>-->
										<!--<end_repair_mass_traffic object="this.defensible"/>
										<end_repair_mass_traffic object="$Defensible"/>-->
										<end_mass_traffic network="$networkid"/>
										<remove_value name="$networkid"/>
									</do_if>
									<set_value name="$Defensible" exact="this.defensible"/>
									<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
									<!--<do_if value="false">-->
										<show_notification caption="'=== MICT Engineer ==='" details="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 1.4'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false" priority="1"/>
										<write_to_logbook category="tips" text="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 1.4'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false"/>
									</do_if>
								</do_elseif>
							<!--</do_if>-->
							<!--<do_else>
								<set_value name="$Defensible" exact="this.defensible"/>
								<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
									<show_notification caption="'=== MICT Engineer ==='" details="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 2'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false" priority="1"/>
									<write_to_logbook category="tips" text="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 2'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false"/>
								</do_if>
							</do_else>-->
						</do_all>
						<remove_value name="$MICT_RepairTargets"/>
					</do_if>
					<do_else>
						<do_if value="$networkid? and @$Defensible != this.defensible">
							<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
								<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 3'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]" queued="false" priority="1"/>
								<write_to_logbook category="tips" text="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 3'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]"/>
							</do_if>

							<!--<end_repair_mass_traffic object="[this.defensible, $Defensible]"/>-->
							<!--<end_repair_mass_traffic object="this.defensible"/>
							<end_repair_mass_traffic object="$Defensible"/>-->
							<end_mass_traffic network="$networkid"/>
							<remove_value name="$networkid"/>
						</do_if>
						<set_value name="$Defensible" exact="this.defensible"/>
						<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
						<!--<do_if value="false">-->
							<show_notification caption="'=== MICT Engineer ==='" details="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 3'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false" priority="1"/>
							<write_to_logbook category="tips" text="'%1 \n Repairing %2 \n Num Repair Targets: %3 \n\n NODE 3'.[this.defensible.knownname, $Defensible.knownname, $MICT_RepairTargets.count, this.defensible.distanceto.{$Defensible}]" queued="false"/>
						</do_if>
					</do_else>
				</do_if>
				<do_else>
					<do_if value="$networkid? and @$Defensible != this.defensible">
						<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
							<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 4'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]" queued="false" priority="1"/>
							<write_to_logbook category="tips" text="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 4'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]"/>
						</do_if>

						<!--<end_repair_mass_traffic object="[this.defensible, $Defensible]"/>-->
						<!--<end_repair_mass_traffic object="this.defensible"/>
						<end_repair_mass_traffic object="$Defensible"/>-->
						<end_mass_traffic network="$networkid"/>
						<remove_value name="$networkid"/>
					</do_if>
					<set_value name="$Defensible" exact="this.defensible"/>
					<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
						<show_notification caption="'=== MICT Engineer ==='" details="'%1 \n Repairing %2 \n\n NODE 4'.[this.defensible.knownname, $Defensible.knownname, this.defensible.distanceto.{$Defensible}]" queued="false" priority="1"/>
						<write_to_logbook category="tips" text="'%1 \n Repairing %2 \n\n NODE 4'.[this.defensible.knownname, $Defensible.knownname, this.defensible.distanceto.{$Defensible}]" queued="false"/>
					</do_if>
				</do_else>
			</do_if>
			<do_else>
				<do_if value="$networkid? and @$Defensible != this.defensible">
					<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
						<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 5'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]" queued="false" priority="1"/>
						<write_to_logbook category="tips" text="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 5'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]"/>
					</do_if>

					<!--<end_repair_mass_traffic object="[this.defensible, $Defensible]"/>-->
					<!--<end_repair_mass_traffic object="this.defensible"/>
					<end_repair_mass_traffic object="$Defensible"/>-->
					<end_mass_traffic network="$networkid"/>
					<remove_value name="$networkid"/>
				</do_if>
				<set_value name="$Defensible" exact="this.defensible"/>
				<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
					<show_notification caption="'=== MICT Engineer ==='" details="'%1 \n Repairing %2 \n\n NODE 5'.[this.defensible.knownname, $Defensible.knownname, this.defensible.distanceto.{$Defensible}]" queued="false" priority="1"/>
					<write_to_logbook category="tips" text="'%1 \n Repairing %2 \n\n NODE 5'.[this.defensible.knownname, $Defensible.knownname, this.defensible.distanceto.{$Defensible}]" queued="false"/>
				</do_if>
			</do_else>
		</do_if>
		<do_else>
			<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and (this.defensible.primarypurpose != objectpurpose.fight)">
				<show_notification caption="'=== MICT Engineer ==='" details="'%1 \n Still repairing %2 \n Components to repair: %3 \n Repairing: %4 \n\n NODE 0'.[this.defensible.knownname, $Defensible.knownname, $MassTrafficTargets.count, $CurrentElement.knownname]" queued="false" priority="1"/>
				<write_to_logbook category="tips" text="'%1 \n Still repairing %2 \n Components to repair: %3 \n Repairing: %4 \n\n NODE 0'.[this.defensible.knownname, $Defensible.knownname, $MassTrafficTargets.count, $CurrentElement.knownname]"/>
			</do_if>
		</do_else>
		<set_command command="command.support" param="$Defensible" chance="if $Defensible == this.defensible then 0 else 100"/>
		<set_command command="command.repair" chance="if $Defensible == this.defensible then 100 else 0"/>
	</add>

	<!--<replace sel="//do_if[@value='this.defensible.isclass.station']/@value">$Defensible.isclass.station</replace>-->

	<replace sel="//do_if[@value='not $CurrentElement.exists and this.defensible.hullpercentage ge $hulldamagelimit']/@value">not $CurrentElement.exists and $Defensible.hullpercentage ge $hulldamagelimit</replace>

	<!-- MICT: check to make sure that the repair target doesn't break between target acquisition and start of repair.
		Marvin's again, but didn't go with the wreck resurrection routine. -->
	<add sel="//do_if[@value='$CurrentElement.exists']" pos="before">
		<do_if value="$Defensible? and $Defensible.isoperational" negate="true">
			<resume label="checkforrepair"/>
		</do_if>
	</add>

	<!-- MICT: repair ships launch welder drones to repair damaged ships and stations. -->
	<replace sel="//launch_repair_drones/@object">this.defensible</replace>
	<!--<replace sel="//launch_repair_drones/@target">this.defensible</replace>-->

	<!-- MICT: Looks like Marvin's right. Since the drones are launched with object="this.defensible" the resulting mass traffic also has object="this.defensible"
		so both find_active_repair_mass_traffic and end_repair_mass_traffic have to refer to object="this.defensible" rather than object="$Defensible"
		which is really weird, but ok.
		
		Nope?
		Not sure. end_repair_mass_traffic object="this.defensible" doesn't cause welders to dock, but neither does end_repair_mass_traffic="$Defensible"
		And do_all exact="this.defensible.units.{unitcategory.welder}.count" counter="$i" doesn't appear to work.
	-->
	<!--<replace sel="//attention[@min='unknown']/actions/do_if[@value='@$networkid']/find_active_repair_mass_traffic/@object">this.defensible</replace>-->
	<remove sel="//attention[@min='unknown']/actions/do_if[@value='@$networkid']/find_active_repair_mass_traffic"/>
	<add sel="//attention[@min='unknown']/actions/do_if[@value='@$networkid']/get_units_in_mass_traffic" pos="after">
		<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and ($Defensible != this.defensible)">
			<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 \n set to repair %3 \n Components to repair: %4 \n Now Repairing: %5'.[$unitamounts.{1}, this.defensible.knownname, $Defensible.knownname, $MassTrafficTargets.count, $CurrentElement.knownname]" queued="false" priority="1"/>
			<write_to_logbook category="tips" text="'%1 drones of \n %2 \n set to repair %3 \n Components to repair: %4 \n Now Repairing: %5'.[$unitamounts.{1}, this.defensible.knownname, $Defensible.knownname, $MassTrafficTargets.count, $CurrentElement.knownname]"/>
			<!--<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 \n set to repair %3 \n Components to repair: %4 \n Damaged Components: %5 \n Now Repairing: %6'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname, $MassTrafficTargets.count, $PossibleElements.count, $CurrentElement.knownname]" queued="false" priority="1"/>
			<write_to_logbook category="tips" text="'%1 drones of \n %2 \n set to repair %3 \n Components to repair: %4 \n Damaged Components: %5 \n Now Repairing: %6'.[this.defensible.units.{unitcategory.welder}.count - this.defensible.availableunits.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname, $MassTrafficTargets.count, $PossibleElements.count, $CurrentElement.knownname]"/>-->
		</do_if>
	</add>

	<!-- MICT: after repairs are done, dock welder drones. -->
	<!--<replace sel="//do_if[@value='not $CurrentElement.exists']/do_if[@value='$Defensible.hullpercentage ge $hulldamagelimit']/end_repair_mass_traffic/@object">[this.defensible, $Defensible]</replace>-->
	<!--<replace sel="//do_if[@value='not $CurrentElement.exists']/do_if[@value='$Defensible.hullpercentage ge $hulldamagelimit']/end_repair_mass_traffic/@object">this.defensible</replace>-->
	<add sel="//do_if[@value='not $CurrentElement.exists']/do_if[@value='$Defensible.hullpercentage ge $hulldamagelimit']/end_repair_mass_traffic" pos="after">
		<!--<end_repair_mass_traffic object="this.defensible"/>-->
		<end_mass_traffic network="$networkid"/>
		<do_if value="$Defensible != this.defensible">
			<set_value name="$Defensible" exact="this.defensible"/>
		</do_if>
		<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and ($Defensible != this.defensible)">
			<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 6'.[this.defensible.units.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]" queued="false" priority="1"/>
			<write_to_logbook category="tips" text="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 6'.[this.defensible.units.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]"/>
		</do_if>
	</add>

	<!--<replace sel="//do_if[@value='$repairratefactor == 0']/do_if[@value='@$networkid']/end_repair_mass_traffic/@object">[this.defensible, $Defensible]</replace>-->
	<!--<replace sel="//do_if[@value='$repairratefactor == 0']/do_if[@value='@$networkid']/end_repair_mass_traffic/@object">this.defensible</replace>-->
	<add sel="//do_if[@value='$repairratefactor == 0']/do_if[@value='@$networkid']/end_repair_mass_traffic" pos="after">
		<!--<end_repair_mass_traffic object="this.defensible"/>-->
		<end_mass_traffic network="$networkid"/>
		<do_if value="$Defensible != this.defensible">
			<set_value name="$Defensible" exact="this.defensible"/>
		</do_if>
		<do_if value="(this.defensible.zone == player.zone) and (this.defensible.owner == faction.player) and ($Defensible != this.defensible)">
			<show_notification caption="'=== MICT Engineer ==='" details="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 7'.[this.defensible.units.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]" queued="false" priority="1"/>
			<write_to_logbook category="tips" text="'%1 drones of \n %2 heading home \n from %3 \n\n NODE 7'.[this.defensible.units.{unitcategory.welder}.count, this.defensible.knownname, $Defensible.knownname]"/>
		</do_if>
	</add>
</diff>
goes in \aiscripts\engineer.ai.xml

Note that it IS possible to force drones to dock. However, this keeps the unused mass traffic networks intact and inaccessible leading to save game bloat and problems later on.
w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans »

Cleaned out all of the commented-out code and notifications from the code above. Sometimes helps to see it laid out here for some reason. Also for anyone who might be curious, and might spot problems.

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<diff>
	<!-- MICT: accelerated repair rates for testing. -->
	<replace sel="//set_object_hull[@object='$CurrentElement']/@exact">100</replace>

	<!-- MICT: If this ship doesn't need to be repaired, look for something to repair.
		Valid targets for repair are l-class and xl-class ships and stations.
		Repair most damaged ships/stations first.
		First priority is still the ship/station where the engineer is stationed.

		Problem: At the moment, prioritization is only by hull damage.
			If something has a hull damaged below threshold, but damaged components, that thing won't be repaired by other ships/stations.
			That ship's/station's own engineer should still handle repairs in that case, however.

		Not really a problem, but not very efficient: this.defensible is set as the repair target if:
			this.defensible is not a MICT ship,
			this.defensible has hull damage above threshold or this.defensible is a combat ship,
			there are no valid repair targets within radar range,
			none of the detected potential repair targets are owned by the same faction that owns this.defensible,
			none of the detected potential repair targets actually needs repair.

			Try to figure out a way to simplify?
			Then again, each do_if/do_else block will only be run once, so might be fine.

			Thanks to Marvin Martian for some help with refining this. -->
	<remove sel="//set_value[@name='$Defensible']"/>

	<add sel="//do_if[@value='player.age le @this.$hacked']" pos="before">
		<do_if value="@$CurrentElement.exists" negate="true">
			<do_if value="this.defensible.isclass.[class.ship_l, class.ship_xl] and this.combinedskill ge 80 and this.defensible.pilot.combinedskill ge 80 and this.defensible.defencenpc.combinedskill ge 80 and this.defensible.units.{unitcategory.welder}.count gt 0">
				<do_if value="this.defensible.primarypurpose != objectpurpose.fight and this.defensible.hullpercentage ge $hulldamagelimit">
					<find_gravidar_contact name="$MICT_RepairTargets" object="this.defensible" functional="true" multiple="true" checkoperational="true" repairable="true" invulnerable="false" indestructible="false">
						<match_distance object="this.defensible" max="this.defensible.maxradarrange"/>
						<match class="[class.ship_l, class.ship_xl, class.station, class.ship_s, class.ship_m]"/>
						<match_relation faction="this.defensible.trueowner" relation="self" comparison="ge"/>
						<match_hull min="$hulldamagelimit" negate="true"/>
					</find_gravidar_contact>
					<do_if value="$MICT_RepairTargets.count ge 1">
						<do_all exact="$MICT_RepairTargets.count" counter="$i">
								<do_if value="$MICT_RepairTargets.{$i}.hullpercentage lt @$Defensible.hullpercentage">
									<do_if value="$networkid? and @$Defensible != $MICT_RepairTargets.{$i}">
										<end_mass_traffic network="$networkid"/>
										<remove_value name="$networkid"/>
									</do_if>
									<set_value name="$Defensible" exact="$MICT_RepairTargets.{$i}"/>
								</do_if>
								<do_elseif value="not $Defensible? and $MICT_RepairTargets.{$i}.hullpercentage lt $hulldamagelimit">
									<do_if value="$networkid? and @$Defensible != $MICT_RepairTargets.{$i}">
										<end_mass_traffic network="$networkid"/>
										<remove_value name="$networkid"/>
									</do_if>
									<set_value name="$Defensible" exact="$MICT_RepairTargets.{$i}"/>
								</do_elseif>
								<do_elseif value="not $Defensible?">
									<do_if value="$networkid? and @$Defensible != this.defensible">
										<end_mass_traffic network="$networkid"/>
										<remove_value name="$networkid"/>
									</do_if>
									<set_value name="$Defensible" exact="this.defensible"/>
								</do_elseif>
								<do_elseif value="$Defensible? and (@$Defensible != this.defensible) and @$Defensible.hullpercentage ge $hulldamagelimit">
									<do_if value="$networkid? and @$Defensible != this.defensible">
										<end_mass_traffic network="$networkid"/>
										<remove_value name="$networkid"/>
									</do_if>
									<set_value name="$Defensible" exact="this.defensible"/>
								</do_elseif>
						</do_all>
						<remove_value name="$MICT_RepairTargets"/>
					</do_if>
					<do_else>
						<do_if value="$networkid? and @$Defensible != this.defensible">
							<end_mass_traffic network="$networkid"/>
							<remove_value name="$networkid"/>
						</do_if>
						<set_value name="$Defensible" exact="this.defensible"/>
					</do_else>
				</do_if>
				<do_else>
					<do_if value="$networkid? and @$Defensible != this.defensible">
						<end_mass_traffic network="$networkid"/>
						<remove_value name="$networkid"/>
					</do_if>
					<set_value name="$Defensible" exact="this.defensible"/>
				</do_else>
			</do_if>
			<do_else>
				<do_if value="$networkid? and @$Defensible != this.defensible">
					<end_mass_traffic network="$networkid"/>
					<remove_value name="$networkid"/>
				</do_if>
				<set_value name="$Defensible" exact="this.defensible"/>
			</do_else>
		</do_if>

		<set_command command="command.support" param="$Defensible" chance="if $Defensible == this.defensible then 0 else 100"/>
		<set_command command="command.repair" chance="if $Defensible == this.defensible then 100 else 0"/>
	</add>

	<replace sel="//do_if[@value='not $CurrentElement.exists and this.defensible.hullpercentage ge $hulldamagelimit']/@value">not $CurrentElement.exists and $Defensible.hullpercentage ge $hulldamagelimit</replace>

	<!-- MICT: check to make sure that the repair target doesn't break between target acquisition and start of repair.
		Marvin's again, but didn't go with the wreck resurrection routine. -->
	<add sel="//do_if[@value='$CurrentElement.exists']" pos="before">
		<do_if value="$Defensible? and $Defensible.isoperational" negate="true">
			<resume label="checkforrepair"/>
		</do_if>
	</add>

	<!-- MICT: repair ships launch welder drones to repair damaged ships and stations. -->
	<replace sel="//launch_repair_drones/@object">this.defensible</replace>

	<!-- MICT: Looks like Marvin's right. Since the drones are launched with object="this.defensible" the resulting mass traffic also has object="this.defensible"
		so both find_active_repair_mass_traffic and end_repair_mass_traffic have to refer to object="this.defensible" rather than object="$Defensible"
		which is really weird, but ok.
		
		Nope?
		Not sure. end_repair_mass_traffic object="this.defensible" doesn't cause welders to dock, but neither does end_repair_mass_traffic="$Defensible"
		And do_all exact="this.defensible.units.{unitcategory.welder}.count" counter="$i" doesn't appear to work.
	-->
	<remove sel="//attention[@min='unknown']/actions/do_if[@value='@$networkid']/find_active_repair_mass_traffic"/>

	<!-- MICT: after repairs are done, dock welder drones. -->
	<add sel="//do_if[@value='not $CurrentElement.exists']/do_if[@value='$Defensible.hullpercentage ge $hulldamagelimit']/end_repair_mass_traffic" pos="after">
		<end_mass_traffic network="$networkid"/>
		<do_if value="$Defensible != this.defensible">
			<set_value name="$Defensible" exact="this.defensible"/>
		</do_if>
	</add>

	<add sel="//do_if[@value='$repairratefactor == 0']/do_if[@value='@$networkid']/end_repair_mass_traffic" pos="after">
		<end_mass_traffic network="$networkid"/>
		<do_if value="$Defensible != this.defensible">
			<set_value name="$Defensible" exact="this.defensible"/>
		</do_if>
	</add>
</diff>
w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans »

UniTrader wrote:1. keep one drone on each Object in reserve which you start on <event_savegame_loaded/> (and recall immediately) -> i think this may give the current network ids for both since from my understanding the network is re-used when already existing
Unfortunately, doesn't work either. Tried a quick preliminary test by getting repair ships to launch 1 drone at a time every time the script cycles. Ran that for two cycles, then checked the resulting save file.

Each successive drone launch results in an entirely new mass traffic network rather than adding it to the existing network:
repair mass traffic network wrote:<network id="[0x1d5b]" starttime="875526.147" space="[0x7029]">
<quotalists>
<quotalist id="[0x1d5c]" starttime="875526.147" continuous="1" startobject="[0x730f]" endobject="[0x730f]">
<quotas>
<quota id="[0x1d5d]" class="repair" amount="1" macro="units_size_xs_welder_drone_macro"/>
</quotas>
</quotalist>
</quotalists>
<involved>
<object id="[0x7029]"/>
<object id="[0x730f]"/>

</involved>
<actuallyinvolved>
<object id="[0x7029]"/>
<object id="[0x730f]"/>
</actuallyinvolved>
<behavior class="repair" numpaths="1" numpoints="3" maxslowroadlength="500">
<weldareas>
<box>
<max x="35.932" y="35.932" z="38.198"/>
<center x="-54.885" y="-14.571" z="-748.738"/>
</box>
<box>
<max x="35.932" y="35.932" z="38.198"/>
<center x="55.003" y="-14.571" z="-748.738"/>
</box>
<box>
<max x="6.801" y="1.712" z="16.306"/>
<center y="-64.016" z="-662.978"/>
</box>
</weldareas>
</behavior>
</network>

<network id="[0x2192]" starttime="875611.208" space="[0x7029]">
<quotalists>
<quotalist id="[0x2193]" starttime="875611.208" continuous="1" startobject="[0x730f]" endobject="[0x730f]">
<quotas>
<quota id="[0x2194]" class="repair" amount="1" macro="units_size_xs_welder_drone_macro"/>
</quotas>
</quotalist>
</quotalists>
<involved>
<object id="[0x7029]"/>
<object id="[0x730f]"/>

</involved>
<actuallyinvolved>
<object id="[0x7029]"/>
<object id="[0x730f]"/>
</actuallyinvolved>
<behavior class="repair" numpaths="1" numpoints="2" maxslowroadlength="500">
<weldareas>
<box>
<max x="35.932" y="35.932" z="38.198"/>
<center x="-54.885" y="-14.571" z="-748.738"/>
</box>
<box>
<max x="35.932" y="35.932" z="38.198"/>
<center x="55.003" y="-14.571" z="-748.738"/>
</box>
</weldareas>
</behavior>
</network>

Return to “X Rebirth - Scripts and Modding”