UNPKG

xsd-lookup

Version:
719 lines (677 loc) 93.8 kB
<?xml version="1.0" encoding="utf-8" ?> <!-- this script should be able to perform all the default checks and make sure a ship docks at the specified destination --> <aiscript name="order.dock" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="aiscripts.xsd" priority="11" version="26"> <order id="DockAt" name="{1041, 441}" description="{1041, 442}" category="internal" canplayercancel="true"> <params> <param name="destination" type="object" default="@this.ship.assigneddock.container" text="{1041, 10027}" comment="Destination. Object"> <input_param name="class" value="if this.ship.isclass.[class.ship_s, class.ship_xs] then [class.station, class.ship_m, class.ship_l, class.ship_xl] else [class.station, class.ship_l, class.ship_xl]"/> </param> <param name="building" type="internal" default="false" text="{1041, 10016}" comment="Building. Whether the purpose of docking is to build, upgrade or repair"/> <param name="trading" type="internal" default="false" text="{1041, 10131}" comment="Trading. Whether the purpose of docking is to trade" /> <param name="allowplayeronly" type="internal" default="false" text="'Allow PlayerOnly'" comment="Allow PlayerOnly. Whether a dock that is exclusive to the player may be used" /> <param name="ventureplatform" type="internal" default="null" text="'Venture Platform'" comment="Venture Platform. Use if the purpose of docking is to go on a venture" /> <param name="useentrypos" type="internal" default="true" text="{1041, 10139}" comment="Use entry position. Use dockmodule entry position"/> <param name="dockfollowers" type="bool" default="this.ship.isunit" text="{1041, 10032}" advanced="true" comment="Dock subordinates. Order subordinates to dock at destination"> <patch value="this.ship.isunit" condition="this.ship.isunit and not $dockfollowers" sinceversion="8"/> </param> <param name="abouttofinish" type="internal" default="false" text="{1041, 10001}" comment="About to finish. calling order is about to finish and can be set to critical"/> <!--<param name="timeout" type="time" default="0s" infinitevalue="0s" text="{1041, 10034}" comment="Duration, Time out"> <input_param name="min" value="0s" /> <input_param name="max" value="10h" /> <input_param name="step" value="30s" /> </param>--> <param name="waittime" type="time" default="if this.ship.isclass.spacesuit then this.ship.oxygentimeremaining else 10min" text="{1041, 10061}" advanced="true" comment="Max wait time. maximum time we are willing to wait for a dock to be assigned"> <input_param name="startvalue" value="10min"/> <input_param name="min" value="0s"/> <input_param name="max" value="10h"/> <input_param name="step" value="30s"/> </param> <param name="store" type="internal" default="false" comment="dock into internal storage if possible"> <patch value="false" sinceversion="19"/> </param> <param name="dockandwaitid" type="internal" default="null" comment="DockAndWait ID. ID of attached DockAndWaitOrder. If $thisship cannot dock, $dockandwaitid is cancelled to prevent the ship repeatedly trying to dock.."/> <param name="callerid" type="internal" default="null" comment="Caller ID. Order ID of the order that called the attached DockAndWait order. Used for failure handling. This script expects that $callerid has the parameter $cannotdock and has handling for that parameter being set to true."/> <param name="isdockfollower" type="internal" default="false" comment="order stems from commander docking with $dockfollowers set."/> <param name="noattackresponse" type="internal" default="false" comment="Will not respond to attacks. Read in interrupt.attacked"> <patch value="false" sinceversion="18"/> </param> <param name="internalorder" type="internal" default="false" comment="Will be passed on to move.generic for blacklist enforcement."/> <param name="noboost" type="internal" default="false" comment="passed into move.generic"> <patch value="false" sinceversion="20"/> </param> <param name="uselocalhighways" type="internal" default="not this.ship.iscapitalship" comment="passed into move.generic"> <patch value="not this.ship.iscapitalship" sinceversion="20"/> </param> <param name="untilplayerleaves" type="internal" default="false"> <patch value="false" sinceversion="23"/> </param> <param name="recallsubordinates" type="internal" default="true" comment="passed into move.generic"> <patch value="true" sinceversion="24"/> </param> <param name="spacesuittransfer" type="internal" default="this.ship.isplayerowned" comment="person in spacesuit transferred to object it docks with. NB: changing this behavior to apply to all factions will likely require some adjustment in MD scripts. Axiom, for example."> <patch value="this.ship.isplayerowned" sinceversion="26"/> </param> <param name="debugchance" type="bool" default="0" advanced="true" text="{1041, 10086}" comment="Print debug output"> <input_param name="truevalue" value="100"/> </param> </params> <requires> <match shiptype="shiptype.lasertower" negate="true"/> </requires> <location object="$destination" condition="$destination.exists"/> </order> <interrupts> <handler> <conditions> <check_any> <event_object_destroyed object="$destination" check="false"/> <event_object_abandoned object="$destination" check="false"/> <check_all> <!-- if $destination apparent ownership changes, regardless of whether or not cover is involved, docking should be cancelled if relations no longer allow docking. only exceptions to this rule are units and subordinates. units should dock in any case. if cover is involved, subordinate cover is handled immediately after commander cover is. --> <event_object_changed_owner object="$destination" check="false"/> <check_value value="$thisship.relationto.{$destination} lt 0"/> <check_any> <check_value value="not $thisship.isunit"/> <check_all> <check_value value="$destination.coverowner"/> <check_value value="$thisship.commander != $destination"/> </check_all> </check_any> </check_all> <event_object_signalled object="$thisship" param="'dockat_abort'"/> </check_any> </conditions> <actions> <debug_text text="'destination: %s %s (%s) fired %s. aborting dock attempt.'.[$destination.idcode, $destination.knownname, $destination, event.name]" chance="$debugchance"/> <abort_called_scripts resume="nodestination"/> </actions> </handler> <handler> <conditions> <check_any> <check_all> <event_object_changed_zone object="$destination" check="false"/> <check_any> <check_value value="event.param.isclass.highway"/> <check_value value="event.param2.isclass.highway"/> </check_any> </check_all> <event_object_changed_sector object="$destination" check="false"/> <check_all> <event_object_dock_unassigned object="$thisship"/> <check_value value="not $movingtozone?"/> </check_all> <event_object_signalled object="$thisship" param="'dockat_reset'"/> </check_any> <check_value value="not $thisship.dock"/> </conditions> <actions> <do_if value="event.name == 'event_object_changed_sector'"> <debug_text text="'destination: %s %s (%s) moved to a different sector. aborting dock attempt and attempting to recover.'.[$destination.idcode, $destination.knownname, $destination]" chance="$debugchance"/> </do_if> <do_elseif value="event.name == 'event_object_changed_zone'"> <debug_text text="'destination: %s %s (%s) moved into, or out of, a highway. aborting dock attempt and attempting to recover.'.[$destination.idcode, $destination.knownname, $destination]" chance="$debugchance"/> </do_elseif> <do_else> <debug_text text="'dock for %s %s (%s) at %s %s (%s) was unassigned. aborting dock attempt and attempting to recover.'.[$thisship.idcode, $thisship.knownname, $thisship, $destination.idcode, $destination.knownname, $destination]" chance="$debugchance"/> </do_else> <abort_called_scripts resume="movetozone"/> </actions> </handler> <handler> <conditions> <event_object_target_invalid object="$thisship" check="false"/> </conditions> <actions> <do_if value="not event.param2 and $destination.isoperational" comment="target invalid unreachable handled in code"> <debug_text text="'%s %s %s unable to dock at %s %s %s. target invalid.\n assigneddock: %s %s\n unreachable? %s'.[$thisship.idcode, $thisship.knownname, $thisship, $destination.idcode, $destination.knownname, $destination, @$thisship.assigneddock.knownname, @$thisship.assigneddock, event.param2]" chance="$debugchance"/> <!--<assert value="false" text="'check debug output for %s %s in %s %s %s'.[this.knownname, this, $thisship.idcode, $thisship.knownname, $thisship]" break="always"/>--> </do_if> <!-- workaround to handle situation where we are too close to a station for octree navigation. we will be doing final approach with steering fcm. fcm reset to default with the script ending. --> <do_if value="event.param2 and not $retry?"> <debug_text text="'%s %s %s was unable to dock at %s %s %s due to target being invalid and unreachable. retrying on steering once.'.[$thisship.idcode, $thisship.knownname, $thisship, $destination.idcode, $destination.knownname, $destination]" chance="$debugchance"/> <set_value name="$retry"/> <abort_called_scripts resume="movetodockingbay"/> </do_if> <do_else> <debug_text text="'retry failed or target invalid but not unreachable. aborting.'" chance="$debugchance"/> <abort_called_scripts resume="nodestination"/> </do_else> </actions> </handler> <handler> <conditions> <event_trade_cancelled tradeoffer="@$callerid.trade"/> <check_value value="@$thisship.order.state != orderstate.critical"/> </conditions> <actions> <debug_text text="'trade was cancelled. aborting dock order.'" chance="$debugchance"/> <abort_called_scripts resume="nodestination"/> </actions> </handler> <handler ref="SectorChangeHandler"/> <handler ref="AttackHandler" /> <handler ref="MissileLockHandler" /> <handler ref="ScannedHandler" /> <handler ref="InspectedHandler"/> <handler ref="TideHandler"/> <!-- Patch used via handler --> <handler> <conditions> <event_object_signalled object="this" param="'patch_reset_dock'"/> </conditions> <actions> <!-- On patch version 16 the label block should be restarted to --> <stop_moving object="this.assignedcontrolled"/> <set_to_default_flight_control_model object="this.assignedcontrolled"/> <abort_called_scripts /> </actions> </handler> </interrupts> <init> <set_value name="$thisship" exact="this.assignedcontrolled"/> <do_if value="this == player.computer" comment="this is sometimes Betty but Betty is not assigned to control this.ship"> <set_value name="$thisship" exact="this.ship"/> </do_if> </init> <patch sinceversion="5"> <do_if value="@$thisship.isoperational"> <set_to_default_flight_control_model object="$thisship"/> </do_if> </patch> <patch sinceversion="10"> <set_value name="$movementdest" exact="$destination"/> <do_if value="@$dock"> <set_value name="$movementdest" exact="$dock"/> </do_if> </patch> <patch sinceversion="11"> <set_value name="$endintargetzone" exact="not $destination.isclass.ship or $destination.zone.isclass.highway"/> </patch> <patch sinceversion="12"> <set_value name="$isdockfollower" exact="false"/> <do_if value="$dockfollowers and @$thisship.commander.isclass.ship and ((($thisship.commander.order.id == 'DockAndWait' or $thisship.commander.order.id == 'DockAt') and $thisship.commander.order.$destination == $destination) or $thisship.commander.hascontext.{$destination})"> <set_value name="$isdockfollower" exact="true"/> </do_if> </patch> <patch sinceversion="13"> <do_if value="this.assignedcontrolled.commander and this.assignedcontrolled.subordinategroupdockoverride and (@this.assignedcontrolled.defaultorder.id == 'DockAndWait') and (this.assignedcontrolled.defaultorder.$destination == this.assignedcontrolled.commander)"> <debug_text text="'%s %s %s subordinate of %s %s %s. resetting default order to escort.'.[@this.assignedcontrolled.idcode, @this.assignedcontrolled.knownname, this.assignedcontrolled, @this.assignedcontrolled.commander.idcode, @this.assignedcontrolled.commander.knownname, this.assignedcontrolled.commander]" filter="savegame"/> <create_order object="this.assignedcontrolled" id="'Escort'" default="true"> <param name="target" value="this.assignedcontrolled.commander"/> </create_order> <do_if value="this.assignedcontrolled.order.id == 'DockAt' and this.assignedcontrolled.order.isparameditable.callerid"> <edit_order_param order="this.assignedcontrolled.order" param="'callerid'" value="this.assignedcontrolled.defaultorder"/> </do_if> </do_if> </patch> <patch sinceversion="15"> <set_value name="$internalorder" exact="false"/> </patch> <patch sinceversion="16"> <debug_text text="'PATCH: setting %s %s %s %s to default flight control model and restarting docking label-block.'.[this.assignedcontrolled.class, this.assignedcontrolled.idcode,this.assignedcontrolled.knownname, this.assignedcontrolled]" filter="savegame"/> <!-- need to patch the movement this way because: it isn't possible to change the flight control model on a ship while it is on a move_to where the fcm is forced to steering, and it isn't possible to use resume and abort_called_scripts in the patch node. --> <do_if value="not $thisship.iscapitalship and @$dockmodule and not $abort? and $thisship.assigneddock and @$dockmodule.haswaypointpath.{$thisship.assigneddock.grouptag}.[tag.dockpath, tag.start]"> <signal_objects object="this" param="'patch_reset_dock'"/> </do_if> </patch> <patch sinceversion="17"> <do_if value="($thisship.zone != $destination.zone)"> <remove_docking_request ship="$thisship" container="$destination"/> <debug_text text="'%s %s %s temporarily removing request to dock with\n%s %s %s.\ndistance to destination: %sm'.[@$thisship.idcode, @$thisship.knownname, @$thisship, @$destination.idcode, @$destination.knownname, $destination, $thisship.distanceto.{$destination}]"/> </do_if> </patch> <patch sinceversion="19"> <set_value name="$store" exact="false"/> </patch> <patch sinceversion="20"> <set_value name="$noboost" exact="false"/> <set_value name="$uselocalhighways" exact="not this.assignedcontrolled.iscapitalship"/> </patch> <patch sinceversion="21"> <set_value name="$time_startdocking" exact="player.age"/> <do_if value="not @$thisship.order.exists or $thisship.order.state != orderstate.critical"> <signal_objects object="$thisship" param="'dockat_reset'"/> </do_if> </patch> <patch sinceversion="23"> <set_value name="$untilplayerleaves" exact="false"/> </patch> <patch sinceversion="24"> <set_value name="$recallsubordinates" exact="true"/> </patch> <patch sinceversion="25"> <do_if value="$thisship.isclass.spacesuit and (not @$thisship.order.exists or $thisship.order.state != orderstate.critical)"> <signal_objects object="$thisship" param="'dockat_reset'"/> </do_if> </patch> <patch sinceversion="26"> <set_value name="$spacesuittransfer" exact="this.assignedcontrolled.isplayerowned"/> </patch> <attention min="unknown"> <actions> <!-- this.$subordinateorders used and cleaned up in order.dock.wait unless order.dock is aborted --> <do_if value="not $subordinateorders?"> <create_list name="$subordinateorders" comment="orders that will be created on the subordinates"/> </do_if> <do_if value="not $destination or not $destination.isoperational"> <resume label="nodestination" /> </do_if> <do_if value="$destination == $thisship"> <resume label="nodestination"/> </do_if> <do_if value="$thisship.towedobject"> <do_if value="$thisship.isplayerowned"> <set_value name="$failuretext" exact="{1045,135}" comment="Unable to dock while towing."/> <resume label="nodestination"/> </do_if> <do_else> <stop_towing_object ship="$thisship"/> </do_else> </do_if> <do_if value="$untilplayerleaves and not player.entity.hascontext.{$thisship}"> <debug_text text="'We were docking for the player but player is no longer aboard. Aborting dock order.'" chance="$debugchance"/> <resume label="nodestination"/> </do_if> <do_if value="$destination.zone.isclass.highway"> <debug_text text="'docking. destination is in a highway.'" chance="$debugchance"/> </do_if> <!-- check if we are currently docked / parked --> <do_if value="$destination"> <do_if value="($thisship.dock and (not $building or $thisship.dock.isbuildingallowed) and (not $trading or $thisship.dock.istradingallowed) and (@$thisship.dock.ventureplatform == $ventureplatform)) or ($thisship.parkedat and ($thisship.parkedat != $destination) and not @$thisship.parkedat.hascontext.{$destination})"> <!-- NB: some ships such as mining drones do not use orders and must dock to be recovered. if they are currently docked and they get to this point, finish undocking and dock again. --> <do_if value="($thisship.container == $destination) and $thisship.order"> <do_if value="$dockfollowers and not $subordinateorders.count"> <set_value name="$subordinates" exact="$thisship.subordinates" /> <set_value name="$locsubordinateorders" exact="[]"/> <do_all exact="$subordinates.count" counter="$i"> <do_if value="$subordinates.{$i}.isunit"> <do_all exact="$subordinates.{$i}.orders.count" counter="$j" reverse="true"> <cancel_order order="$subordinates.{$i}.orders.{$j}"/> </do_all> <do_if value="$thisship.commander"> <!-- Change commander of subordinates, to not let them promote when this ship docks --> <set_object_commander object="$subordinates.{$i}" commander="$thisship.commander" /> </do_if> </do_if> <do_elseif value="not $subordinates.{$i}.iscapitalship and @$subordinates.{$i}.dock.container != $thisship"> <do_if value="$internalorder and (not $callerid or not $callerid.exists or not $callerid.$subordinateorders?)"> <!-- this happens when the DockAndWait order of a ship is docked while it is already at DockAt. will result in the ship immediately undocking. safe to simply not order subordinates to dock in this case. --> <debug_text text="'order.dock called with dockfollowers but no callerid. we have no place to store the subordinateorders. NOT ordering subordinates to dock.'" chance="$debugchance"/> </do_if> <do_else> <do_all exact="$subordinates.{$i}.orders.count + 1" counter="$j"> <do_if value="$j gt $subordinates.{$i}.orders.count"> <set_value name="$immediatedockorder"/> </do_if> <do_elseif value="$subordinates.{$i}.orders.{$j}.id == 'Resupply' or $subordinates.{$i}.orders.{$j}.id == 'Equip' or $subordinates.{$i}.orders.{$j}.id == 'Repair' or $subordinates.{$i}.orders.{$j}.id == 'DockAt' or $subordinates.{$i}.orders.{$j}.id == 'DockAndWait'"> <set_value name="$immediatedockorder" exact="false"/> <break/> </do_elseif> </do_all> <create_order object="$subordinates.{$i}" name="$order_sub" id="'DockAndWait'" immediate="$immediatedockorder"> <param name="destination" value="$destination"/> <param name="dockfollowers" value="$dockfollowers"/> <param name="isdockfollower" value="true"/> <param name="callerid" value="if $dockandwaitid then $dockandwaitid else $callerid"/> <param name="internalorder" value="true"/> <param name="debugchance" value="$debugchance"/> </create_order> <debug_text text="player.age + ': 1 %s %s %s ordering %s %s %s to dock. sub order: %s, this order: %s, caller: %s'.[@this.assignedcontrolled.idcode, @this.assignedcontrolled.knownname, this.assignedcontrolled, @$subordinates.{$i}.idcode, @$subordinates.{$i}.knownname, $subordinates.{$i}, $order_sub, $thisship.order, @$callerid.id]" chance="0"/> <append_to_list name="$locsubordinateorders" exact="$order_sub"/> <debug_text text="'adding order: %s %s for %s %s to subordinateorders. num recorded orders: %s'.[$order_sub.id, $order_sub, $subordinates.{$i}.knownname, $subordinates.{$i}, $locsubordinateorders.count]" chance="$debugchance"/> <remove_value name="$order_sub"/> <remove_value name="$immediatedockorder"/> </do_else> </do_elseif> </do_all> <do_if value="$locsubordinateorders?"> <set_value name="$subordinateorders" exact="$locsubordinateorders"/> <!-- NB: $subordinateorders has to be passed into both $callerid and $dockandwaitid. $callerid to handle undocking, and in $dockandwaitid in case this is destroyed after this order but before callerid runs. --> <do_if value="@$callerid.exists and $callerid.$subordinateorders? and $locsubordinateorders.count"> <debug_text text="'passing %s subordinate orders to order %s'.[$locsubordinateorders.count, $callerid.id]" chance="$debugchance"/> <edit_order_param order="$callerid" param="'subordinateorders'" value="$locsubordinateorders"/> </do_if> <do_if value="@$dockandwaitid.exists and $dockandwaitid.$subordinateorders? and $locsubordinateorders.count"> <debug_text text="'passing %s subordinate orders to order %s'.[$locsubordinateorders.count, $dockandwaitid.id]" chance="$debugchance"/> <edit_order_param order="$dockandwaitid" param="'subordinateorders'" value="$locsubordinateorders"/> </do_if> <remove_value name="$locsubordinateorders"/> </do_if> <remove_value name="$subordinates" /> </do_if> <debug_text text="'we are already docked at our destination!'" chance="$debugchance" /> <resume label="finish"/> </do_if> <run_script name="'move.undock'"> <param name="debugchance" value="$debugchance"/> </run_script> </do_if> </do_if> <label name="start"/> <do_if value="not $destination or not $destination.isoperational"> <resume label="nodestination"/> </do_if> <!-- see if there is a possible dock location --> <find_dockingbay object="$destination" name="$dock"> <match_dock size="$thisship.docksize" trading="$trading" building="$building" allowplayeronly="$allowplayeronly" ventureplatform="$ventureplatform" ventureronly="$ventureplatform.isoperational" storage="false"/> <match_relation_to object="$thisship" comparison="not" relation="enemy"/> </find_dockingbay> <do_if value="$dock == null"> <do_if value="((@$destination.type == shiptype.resupplier) or (@$destination.type == shiptype.carrier)) and not $thisship.hasrelation.enemy.{$destination} and $thisship.iscapitalship"> <do_if value="not $destination.zone.isclass.highway"> <set_value name="$park"/> </do_if> <do_else> <debug_text text="'destination %s %s %s is in a highway. waiting to try again.'" chance="$debugchance"/> <!-- if $destination is in a highway, wait for it to leave the highway before telling it to stop. --> <wait sinceversion="2" min="17s" max="31s"> <interrupt> <conditions> <check_any> <check_all> <event_object_changed_zone object="$destination"/> <check_value value="not event.param.isclass.highway"/> </check_all> <event_object_destroyed object="$destination"/> </check_any> </conditions> </interrupt> </wait> <resume label="start"/> </do_else> </do_if> <do_else> <debug_text text="'could not find valid dock for \'%1\' at destination \'%2\'(%3) - %4!'.[$thisship.macro.id, $destination.macro.id, $destination, this.cluster.knownname]" chance="$debugchance" /> <resume label="nodestination" /> </do_else> </do_if> <do_else> <debug_text text="'found docking bay: %1 on %4. storage? %2 external? %3'.[$dock.macro.id, $dock.isstorage, $dock.external, $destination.macro.id]" chance="$debugchance"/> </do_else> <do_if value="$thisship.assigneddock.exists and (not (if $thisship.isunit then $thisship.assigneddock.isunitdockingallowed else $thisship.assigneddock.isdockingallowed) or ($thisship.assigneddock.container != $destination) or ($building and not $thisship.assigneddock.isbuildingallowed) or ($trading and not $thisship.assigneddock.istradingallowed) or (@$thisship.assigneddock.ventureplatform != $ventureplatform))"> <debug_text text="'assigned dock does not meet our requirements'" chance="$debugchance"/> <do_if value="$thisship.assigneddock.container != $destination"> <debug_text text="'the dock assigned to %s %s (%s) is not connected to our destination %s %s (%s). it is at %s %s (%s).'.[$thisship.idcode, $thisship.knownname, $thisship, $destination.idcode, $destination.knownname, $destination, $thisship.assigneddock.container.idcode, $thisship.assigneddock.container.knownname, $thisship.assigneddock.container]" chance="$debugchance"/> </do_if> <!--<assert value="$thisship.assigneddock.container == $destination" text="'the dock assigned to %s %s (%s) is not connected to our destination %s %s (%s). it is at %s %s (%s).'.[$thisship.idcode, $thisship.knownname, $thisship, $destination.idcode, $destination.knownname, $destination, $thisship.assigneddock.container.idcode, $thisship.assigneddock.container, $thisship.assigneddock.container.knownname]" break="always"/>--> <!-- this clears the dock assignment, which might have been left over from undocking (the dock is automatically unassigned at a minimum distance which might not have been reached yet) --> <debug_text text="'clear docking request for dock %s at %s(%s)'.[$thisship.assigneddock, $thisship.assigneddock.container.knownname, $thisship.assigneddock.container]" chance="$debugchance" /> <remove_docking_request ship="$thisship" container="$thisship.assigneddock.container" immediate="true" /> </do_if> <label name="movetozone" /> <do_if value="not $destination.isoperational"> <debug_text text="'destination is not operational. aborting.'" chance="$debugchance"/> <resume label="nodestination"/> </do_if> <!-- After the checks, set command dock --> <set_command command="command.dockat" param="$destination" /> <!-- leave formation (if there is any) as that would block our movement --> <do_if value="not $dockfollowers"> <!-- if only we should dock, leave current formation --> <leave_formation object="$thisship" /> </do_if> <do_else> <do_all exact="this.assignedcontrolled.subordinates.count" counter="$i"> <set_value name="$locsubordinate" exact="this.assignedcontrolled.subordinates.{$i}"/> <do_if value="$locsubordinate.isoperational and not $locsubordinate.dock and $locsubordinate.isformationwingman and ($locsubordinate.formationleader == $thisship)"> <!-- if we must tell followers to dock, create a line formation to go all together --> <leave_formation object="$locsubordinate"/> <create_formation leader="$thisship" follower="$locsubordinate" formation="formationshape.lineastern" param="$thisship.size * 2"/> <break/> </do_if> </do_all> <remove_value name="$locsubordinate"/> </do_else> <!-- if necessary order the ship to move to the correct zone --> <set_value name="$movementdest" exact="$destination"/> <do_if value="@$dock.isoperational and not $destination.isclass.ship"> <set_value name="$movementdest" exact="$dock"/> </do_if> <set_value name="$canmovecloser"/> <debug_text text="'check if already in correct zone. this zone: %s %s, destination zone: %s %s'.[this.zone.knownname, this.zone, $destination.zone.knownname, $destination.zone]" chance="$debugchance"/> <do_if value="$alwaysmove? or (this.sector != $destination.sector) or ((($destination.isclass.ship and not $destination.zone.isclass.highway) or this.zone != $movementdest.zone) and $thisship.bboxdistanceto.{$movementdest} gt 10km)"> <debug_text text="'move to destination \n this zone: %1\n this sector: %2\n destination sector: %3\n distance to destination: %4'.[this.zone, this.sector, $destination.sector, $thisship.bboxdistanceto.{$destination}]" chance="$debugchance"/> <include_interrupt_actions ref="NPCUseCase_NavOrder"/> <!-- if we're far enough away that we have to do movetozone, remove any existing docking requests to clear the dock for other ships until we get closer. --> <remove_docking_request ship="$thisship" container="$destination"/> <set_value name="$movingtozone"/> <set_value name="$endintargetzone" exact="not $destination.isclass.ship or $destination.zone.isclass.highway"/> <!-- NB: if destination is in a highway, move.generic, in this configuration, will finish when it gets to the same highway. --> <run_script name="'move.generic'" result="$movesuccess"> <param name="destination" value="$movementdest"/> <param name="endintargetzone" value="$endintargetzone"/> <param name="strictblacklist" value="$internalorder"/> <param name="noboost" value="$noboost"/> <param name="uselocalhighways" value="$uselocalhighways"/> <param name="recallsubordinates" value="$recallsubordinates"/> <param name="debugchance" value="$debugchance"/> </run_script> <do_if value="$endintargetzone"> <remove_value name="$canmovecloser"/> </do_if> <remove_value name="$alwaysmove"/> <remove_value name="$endintargetzone"/> <remove_value name="$movingtozone"/> <wait min="300ms" max="750ms"/> <do_if value="not $movesuccess"> <do_if value="$internalorder"> <set_value name="$loctarget" exact="$thisship"/> <include_interrupt_actions ref="GetBlacklistgroup"/> <remove_value name="$loctarget"/> </do_if> <!-- better would be $thisship.gatedistance.{$destination}.{$blacklistgroup}.{$thisship} ge 0 or (not $internalorder and $thisship.gatedistance.{$destination} ge 0) but evaluating $internalorder is much cheaper than evaluating gatedistance. --> <do_if value="($internalorder and $thisship.gatedistance.{$destination}.{$blacklistgroup}.{$thisship} ge 0) or (not $internalorder and $thisship.gatedistance.{$destination} ge 0)"> <resume label="movetozone"/> </do_if> <do_else> <set_value name="$failuretext" exact="{1045, 101}" comment="Unable to reach destination."/> <debug_text text="'no path to destination. aborting.'" filter="error"/> <resume label="nodestination"/> </do_else> </do_if> <do_elseif value="(this.sector != $destination.sector) or ((($destination.isclass.ship and not $destination.zone.isclass.highway) or (this.zone != $movementdest.zone and not $movementdest.zone.adjacentzones.indexof.{this.zone})) and $thisship.bboxdistanceto.{$movementdest} gt [10km, $destination.size/2].max)"> <debug_text text="'%s %s %s did not arrive at destination %s %s %s after return from move.generic. looping back.\n cond 1: %s, this sector: %s %s, destination sector: %s %s\n cond 2: %s, this zone: %s %s, destination zone: %s %s, distance: %sm\n cond 3: %s, in highway: %s, destination in highway: %s'.[this.assignedcontrolled.idcode, this.assignedcontrolled.knownname, this.assignedcontrolled, $destination.idcode, $destination.knownname, $destination, this.sector != $destination.sector, this.sector.knownname, this.sector, $destination.sector.knownname, $destination.sector, (this.zone != $destination.zone) and $thisship.bboxdistanceto.{$destination} gt 10km, this.zone.knownname, this.zone, $destination.zone.knownname, $destination.zone, $thisship.bboxdistanceto.{$destination}, this.zone.isclass.highway != $destination.zone.isclass.highway, this.zone.isclass.highway, $destination.zone.isclass.highway]" chance="$debugchance"/> <!--<assert value="false" text="'check debug output for ' + this" break="always"/>--> <resume label="movetozone"/> </do_elseif> </do_if> <!--<remove_value name="$movementdest"/>--> <!-- tell subordinates to dock as well --> <break_formation object="$thisship" /> <label name="waitfordockslot" /> <do_if value="not $destination.isoperational"> <resume label="nodestination" /> </do_if> <do_if value="$park?"> <do_if value="not $destination.zone.isclass.highway and not $destination.parkedat and not $destination.assigneddock and (@$destination.order.state != orderstate.critical or (@$destination.order.id == 'WaitForSignal' and $destination.order.$releasesignal == ['resupply_proceed'] and $destination.order.$signaller == this.assignedcontrolled))"> <do_if value="@$destination.order.id != 'WaitForSignal' or $destination.order.$releasesignal != ['resupply_proceed'] or $destination.order.$signaller != this.assignedcontrolled"> <!-- moved from label start. wait until the last minute since destination will have to stop and wait for us. --> <create_order id="'WaitForSignal'" object="$destination" immediate="true"> <param name="releasesignal" value="['resupply_proceed']"/> <param name="signaller" value="this.assignedcontrolled"/> <param name="allowparked" value="true"/> <param name="setcritical" value="true"/> </create_order> </do_if> <run_script name="'move.park'" result="$parksuccess" sinceversion="2"> <param name="destination" value="$destination"/> <param name="sendreleasesignal" value="['resupply_proceed']"/> <param name="debugchance" value="$debugchance"/> </run_script> <do_if value="$parksuccess"> <debug_text text="player.age + ' now parked at ' + $destination.knownname" chance="$debugchance"/> <resume label="finish"/> </do_if> <do_else> <resume label="nodestination"/> </do_else> </do_if> <do_else> <debug_text text="'destination %s %s %s is busy and we have to park. waiting to try again.\nin a highway: %s\nparkedat: %s\ncritical order: %s\ndocking at: %s'.[@$destination.idcode, @$destination.knownname, $destination, $destination.zone.isclass.highway, $destination.parkedat, (@$destination.order.state != orderstate.critical), $destination.assigneddock]" chance="$debugchance"/> <wait min="19s" max="29s" sinceversion="22"/> <resume label="movetozone"/> </do_else> </do_if> <!-- waiting to dock --> <set_command_action commandaction="commandaction.waitingtodock" param="player.occupiedship" /> <do_if value="$destination.zone.isclass.highway"> <!-- in this case, simply allow the highway to sweep us along until either we or destination leaves the highway. --> <debug_text text="'destination is in a highway and we were about to approach to dock. waiting until we or destination leaves the highway.'" chance="$debugchance"/> <wait comment="$destination leaving the highway should be caught by the global handler."> <interrupt> <conditions> <event_object_changed_zone object="$thisship"/> <check_value value="not event.param.isclass.highway"/> </conditions> </interrupt> </wait> <debug_text text="'wait done. left the highway.'" chance="$debugchance"/> <resume label="movetozone"/> </do_if> <set_value name="$time_startdocking" exact="player.age"/> <do_if value="(($thisship.distanceto.{$destination} + $thisship.size / 2.0 + $destination.size / 2.0) gt 10km and ($thisship != player.occupiedship))"> <debug_text text="'moving to approach position.'" chance="$debugchance"/> <!-- we are not necessarily going to dock at $dock, but it would be a useful gathering point for ships about to dock. --> <do_if value="not $pos_approach?"> <do_if value="@$dock.isoperational"> <!-- NB: approach pos is relative to $destination. changed to use $dock's position relative to $destination. actual movement will be to a safepos close to this position. --> <create_position name="$pos_approach" space="$destination" object="$dock"/> <debug_text text="'the approach position to the closest valid %1 dock of %2 is at %3'.[$thisship.docksize, $destination.knownname, $pos_approach]" chance="$debugchance"/> <set_value name="$list_poscomponents" exact="[]"/> <append_to_list name="$list_poscomponents" exact="$pos_approach.x"/> <append_to_list name="$list_poscomponents" exact="$pos_approach.y"/> <append_to_list name="$list_poscomponents" exact="$pos_approach.z"/> <do_all exact="$list_poscomponents.count" counter="$i"> <do_if value="$list_poscomponents.{$i} lt 0"> <set_value name="$list_poscomponents.{$i}" exact="-$list_poscomponents.{$i}"/> </do_if> </do_all> <debug_text text="$list_poscomponents" chance="0"/> <!-- if docking at a stationary object, would be good to avoid needless movement on the y-axis, especially if the object docking is a capital ship. --> <!--<do_if value="$destination.isclass.ship and $list_poscomponents.{2} gt $list_poscomponents.{1}">--> <do_if value="$destination.isclass.ship or ($list_poscomponents.{2} gt $list_poscomponents.{1} and $list_poscomponents.{2} gt $list_poscomponents.{3})"> <do_if value="$pos_approach.y ge 0"> <set_value name="$quadrant_dock" exact="quadrant.up"/> </do_if> <do_else> <set_value name="$quadrant_dock" exact="quadrant.down"/> </do_else> </do_if> <!-- if docking at a ship, would be good to avoid the front so as to avoid needless collision avoidance, and would be good to avoid the rear of the ship since the engines burn that way. --> <do_elseif value="$list_poscomponents.{3} gt $list_poscomponents.{1} and $list_poscomponents.{3} gt $list_poscomponents.{2}"> <!--<do_elseif value="not $destination.isclass.ship and $list_poscomponents.{3} gt $list_poscomponents.{1} and $list_poscomponents.{3} gt $list_poscomponents.{2}">--> <do_if value="not $destination.isclass.ship and $pos_approach.z gt 0"> <set_value name="$quadrant_dock" exact="quadrant.front"/> </do_if> <do_else> <set_value name="$quadrant_dock" exact="quadrant.back"/> </do_else> </do_elseif> <!-- positions on the x-axis relative to $destination should be safe in any case. --> <do_else> <do_if value="$pos_approach.x gt 0"> <set_value name="$quadrant_dock" exact="quadrant.right"/> </do_if> <do_else> <set_value name="$quadrant_dock" exact="quadrant.left"/> </do_else> </do_else> <remove_value name="$list_poscomponents"/> <debug_text text="$quadrant_dock" chance="$debugchance"/> </do_if> <do_else> <debug_text text="'dock is no longer operational. checking again. this should not spam.'" chance="$debugchance"/> <find_dockingbay object="$destination" name="$dock"> <match_dock size="$thisship.docksize" storage="false"/> <match_relation_to object="$thisship" comparison="not" relation="enemy"/> </find_dockingbay> <do_if value="not $dock"> <debug_text text="'could not find valid dock for \'%1\' at destination \'%2\'(%3) - %4!'.[$thisship.macro.id, $destination.macro.id, $destination, this.cluster.knownname]" chance="$debugchance"/> <resume label="nodestination"/> </do_if> <do_else> <do_if value="@$dock.isoperational and not $destination.isclass.ship"> <!-- update $movementdest in case $dock as changed --> <set_value name="$movementdest" exact="$dock"/> </do_if> <resume label="waitfordockslot"/> </do_else> </do_else> </do_if> <!--<get_safe_pos result="$safepos" zone="$destination.zone" object="$destination" radius="$thisship.size * 2" directionobject="$destination" direction="$quadrant_dock" ignored="$thisship"/>--> <get_safe_pos result="$safepos" zone="$destination.zone" value="$pos_approach" object="$destination" radius="$thisship.size * 2" directionobject="$destination" direction="$quadrant_dock" max="if not $thisship.iscapitalship then ($thisship.size * 2) else 0" ignored="$thisship"/> <create_orientation name="$orientation" orientation="look_at" refobject="$destination"> <position value="$safepos"/> </create_orientation> <!-- translate safepos into the coordinate space of $destination. --> <create_position name="$safepos" space="$destination" value="$safepos" object="$destination.zone"/> <debug_text text="'\ndestination pos: %1\napproach pos: %2\nparking pos: %3\ndestination zone: %4, my zone: %5'.[$destination.position, $pos_approach, $safepos, $destination.zone, this.zone]" chance="$debugchance"/> <!-- move closer to the destination to do: possible problem if $destination goes through a jumpgate or moves to a highway. --> <do_if value="$debugchance gt 0"> <do_if value="@$thisship.sector"> <create_position name="$debug_sector_pos" object="$thisship" space="$thisship.sector"/> <debug_text text="'location info for object=%2 at %1\n zone: %3, position: %4\n sector: %5, position: %6'.[player.age, $thisship, this.zone, $thisship.position, this.sector, $debug_sector_pos]"/> </do_if> <debug_text text="'move_to(403) destination=%1 position=%2 distance=%3'.[$destination, $safepos, $thisship.distanceto.[$destination, $safepos]]"/> </do_if> <do_if value="($thisship.distanceto.{$destination} gt $destination.distanceto.[$destination, $safepos])"> <move_to object="$thisship" destination="$destination" finishonapproach="true" flightbehaviour="flightbehaviour.generic" forceposition="false" forcerotation="false" travel="@$thisship.travel.active or (($thisship.distanceto.[$destination, $safepos] / [$thisship.maxspeed, 1m].max)s gt 60s)"> <position value="$safepos"/> <rotation value="$orientation"/> <!--<interrupt_after_time time="0s"/>--> </move_to> <!-- only useful if interrupt_after_time time="0s" above is removed and you actually are at parking position. --> <debug_text text="'at parking position. distance to destination: %1, distance to approachpos: %2.'.[$thisship.distanceto.{$destination}, $thisship.distanceto.[$destination, $pos_approach]]" chance="$debugchance"/> </do_if> <do_else> <debug_text text="'skipping parking position. my distance to destination: %s. destination distance to safepos: %s'.[$thisship.distanceto.{$destination}, $destination.distanceto.[$destination, $safepos]]" chance="$debugchance"/> </do_else> <remove_value name="$safepos"/> </do_if> <label name="requestdock"/> <!-- ok, everything checks out, now start the docking procedure and request approach path --> <!-- if not trading, dock.istradingallowed is fine. same with not building. --> <do_if value="not $thisship.assigneddock.exists or ($thisship.assigneddock.container != $destination) or not (if $thisship.isunit then $thisship.assigneddock.isunitdockingallowed else $thisship.assigneddock.isdockingallowed) or ($building and not $thisship.assigneddock.isbuildingallowed) or ($trading and not $thisship.assigneddock.istradingallowed) or (@$thisship.assigneddock.ventureplatform != $ventureplatform)"> <do_if value="not $thisship.isunit and (($isdockfollower and $destination != $thisship.commander) or $thisship.subordinates.count) and $thisship.allcommanders.indexof.{$destination} and $destination.defencenpc"> <debug_text text="'%s %s %s docking at commander %s %s %s. someone already docking: %s'.[@$thisship.idcode, @$thisship.knownname, $thisship, @$destination.idcode, @$destination.knownname, $destination, @$destination.defencenpc.$blockingdockapproach]" chance="$debugchance"/> <do_if value="@$destination.defencenpc.$blockingdockapproach.isoperational and ($thisship.allcommanders.indexof.{$destination.defencenpc.$blockingdockapproach} or ($destination.defencenpc.$blockingdockapproach == $thisship))"> <debug_text text="'dock approach is blocked by our commander or us. proceeding to request dock.'" chance="$debugchance"/> </do_if> <do_elseif value="not @$destination.defencenpc.$blockingdockapproach.isoperational and ($thisship.subordinates.count or ($thisship.commander.dock and $thisship.commander.hascontext.{$destination}))"> <debug_text text="'dock approach is not blocked. blocking approach and requesting dock.'" chance="$debugchance"/> <do_if value="$thisship.subordinates.count"> <!-- single ships docking should not block the dock approach. --> <set_value name="$destination.defencenpc.$blockingdockapproach" exact="$thisship"/> </do_if> </do_elseif> <do_else> <debug_text text="'approach to dock is blocked by %s %s %s. waiting to request again.'.[@$destination.defencenpc.$blockingdockapproach.idcode, @$destination.defencenpc.$blockingdockapproach.knownname, @$destination.defencenpc.$blockingdockapproach]" chance="$debugchance"/> <wait min="5s" max="10s" sinceversion="6"/> <resume label="requestdock"/> </do_else> </do_if> <do_else> <debug_text text="'no need to wait. proceeding to request dock.'" chance="$debugchance"/> </do_else> <debug_text text="'request docking'" chance="$debugchance" /> <request_docking ship="$thisship" container="$destination" highpriority="$thisship.isunit" requirebuilding="$building" requiretrading="$trading" allowplayeronly="$allowplayeronly" ventureronly="$ventureplatform.isoperational" ventureplatform="$ventureplatform" queuedresult="$queuedresult" grantedresult="$grantedresult" /> <do_if value="$queuedresult"> <!-- NB: if $canmovecloser, we did not do initial approach or $destination is a ship that was not in a highway. --> <do_if value="$canmovecloser? and $thisship.bboxdistanceto.{$destination} gt 1km"> <debug_text text="'docking request was queued and we can move closer. moving closer to target. distance to destination: %sm, distance to dock: %sm'.[$thisship.bboxdistanceto.{$destination}, $thisship.distanceto.{$movementdest} - $thisship.size / 2]" chance="$debugchance"/> <set_value name="$alwaysmove"/> <resume label="movetozone"/> </do_if> <debug_text text="'waiting for free dock'" chance="$debugchance" /> <do_if value="not $thisship.assigneddock.exists"> <do_if value="(@$thisship.defaultorder.id == 'Escort') and @$t