Skip to content

Instantly share code, notes, and snippets.

@AndrewLipscomb
Last active February 11, 2018 09:31
Show Gist options
  • Save AndrewLipscomb/440617bd421ee7f177101fc6c445ab11 to your computer and use it in GitHub Desktop.
Save AndrewLipscomb/440617bd421ee7f177101fc6c445ab11 to your computer and use it in GitHub Desktop.
Dock Agent Decoded
* This command frequently resets itself (gosub Reboot:) to avoid the DA getting stuck.
set script command: [COMMAND_DOCK_AGENT]
skip if [HOMEBASE]-> exists
return null
$scriptName = get script name
= [THIS]-> call script 'Lib.Gen.SetEIAutoStartParameters' : Args=null ScriptName=$scriptName
[THIS]-> connect ship command/signal [SIGNAL_ATTACKED] to script 'Sig.Attacked.DockAgent' with prio 100
[THIS]-> set local variable: name='mayhem_jobInfo' value=null
[THIS]-> set local variable: name='andrew_foundLegitJob' value=[FALSE]
[THIS]-> set local variable: name='andrew_waitConditionValidated' value=[FALSE]
Restart:
= [THIS]-> call script 'Lib.Gen.ColourShipName' : String='*da' Colour=null OnlySearchLastThreeForDigits=[FALSE] OnlyReturnString=[FALSE] Ship=[THIS]
$fuelJumps = [THIS]-> get jumpdrive fuel resupply
$autojump = [THIS]-> is autojump activated
if $fuelJumps == 0 OR !$autojump
$maxJumps = [HOMEBASE]-> get max trade jumps
$fuelNeeded = $maxJumps * 2
[THIS]-> set jumpdrive fuel resupply: amount=$fuelNeeded
[THIS]-> set autojump active: [TRUE]
[THIS]-> autojump minimum jumps= 0
end
gosub CheckNewVersion:
gosub GoHome:
gosub GetVariables:
gosub GetAJob:
gosub Reboot:
* TODO
* - When a ship doesn`t load or buy everything he wanted ($neededWares), he should look for another source instead of going home. (should be quite rare though)
return null
* *****************************************************************************
CheckNewVersion:
do if is a new script version available
gosub Reboot:
endsub
GoHome:
if [ENVIRONMENT] != [HOMEBASE]
$homebaseSector = [HOMEBASE]-> get sector
if [DOCKEDAT]-> exists
$dockedAtOwner = [DOCKEDAT]-> get owner race
do if $dockedAtOwner == [Player]
gosub QuickRefuel:
end
do if [SECTOR] != $homebaseSector
= [THIS]-> call script 'Lib.Cmd.Refuel.Pre' : Destination=[HOMEBASE] MininumJumpRange=0
[THIS]-> set destination to [HOMEBASE]
[THIS]-> set orders string sprintf: fmt= 'Returning home' , null , null , null , null , null
= [THIS]-> call script '!move.returntohomebase' : argument1=[HOMEBASE]
[THIS]-> set destination to null
end
= [THIS]-> call script 'Lib.DropWares' :
gosub RefuelFromHomebase:
endsub
RefuelFromHomebase:
if [ENVIRONMENT] == [HOMEBASE]
$ecell = [HOMEBASE]-> get amount of ware {Energy Cells} in cargo bay
$fuel = [THIS]-> get resupply fuel required
do if $fuel > 0 AND $ecell >= $fuel
= [THIS]-> load $fuel units of {Energy Cells}
end
endsub
GetVariables:
$homebaseSector = [HOMEBASE]-> get sector
$homebaseShips = [HOMEBASE]-> get owned ships: class/type=null
$logistics = [HOMEBASE]-> get local variable: name='mayhem_logistics'
$jobs = table get $logistics ( 'jobs' )
$thresholds = table get $logistics ( 'thresholds' )
* Sort jobs by priority.
$data = array alloc: size=0
$sort = array alloc: size=0
for each $job in array $jobs
$i = table get $job ( 'priority' )
append $i to array $sort
append $job to array $data
end
$jobs = sort array: data=$data sort values=$sort
$jobs = reverse array $jobs
endsub
GetAJob:
while [HOMEBASE]-> get station pause traders
[THIS]-> set orders string sprintf: fmt= 'Paused' , null , null , null , null , null
= wait 10000 ms
gosub GoHome:
end
* if not [THIS]-> get local variable: name=`mayhem_jobInfo`
* [THIS]-> set orders string sprintf: fmt= `Looking for a job` , null , null , null , null , null
* = wait randomly from 8000 to 16000 ms
* end
[THIS]-> set local variable: name='mayhem_jobInfo' value=null
for each $job in array $jobs
$id = table get $job ( 'id' )
$shipsOnJob = [HOMEBASE]-> call script 'Mayhem.GetShipsOnJob' : id=$id returnLength=[TRUE]
$maxShips = table get $job ( 'maxShips' )
$pause = table get $job ( 'pause' )
if $shipsOnJob < $maxShips AND !$pause
$task = table get $job ( 'task' )
$ware = table get $job ( 'ware' )
if [THIS]-> can transport ware $ware
$target = table get $job ( 'target' )
if not $target
$targetType = 'Trade'
$tradePrice = table get $job ( 'tradePrice' )
else
if is datatype[$target] == [DATATYPE_SECTOR]
$targetType = 'Sector'
else if is datatype[$target] == [DATATYPE_STATION]
$targetType = 'Sanctuary'
end
end
* We do not check target thresholds / pause state here, because we want the ship to accept the job even if they are invalid / on (in that case, the ship will wait on this same job).
$sanctuaryThreshold = table get $job ( 'sanctuaryThreshold' )
$sanctuaryStock = [HOMEBASE]-> get amount of ware $ware in cargo bay
if ($task == 0 AND $sanctuaryStock < $sanctuaryThreshold) OR ($task == 1 AND $sanctuaryStock > $sanctuaryThreshold)
* In case we target a Sanctuary, if it has no stock, no need to go.
* if ($task == 0 AND $targetType == `Sanctuary`)
* $sourceStock = $target -> get amount of ware $ware in cargo bay
* do if $sourceStock == 0
* continue
* end
* We accept the job.
$cargoLoad = table get $job ( 'cargoLoad' )
$cargoLoadQty = table get $job ( 'cargoLoadQty' )
$cargoLoadQty.s = convert number $cargoLoadQty to string
$waitCargo = table get $job ( 'waitCargo' )
[THIS]-> set local variable: name='mayhem_jobInfo' value=$job
* Andrew - call the true target function here. This should "validate" the jobs endpoint threshold conditions
gosub GetTrueTarget:
* Get result of validation
$wasSuccess = [THIS]-> get local variable: name='andrew_foundLegitJob'
* Using a local var as a tribool. True means valid job, false means invalid job, null (else) means nothing found
if $wasSuccess == [TRUE]
gosub AndrewValidateWaitingForCargoCondition:
$waitValidated = [THIS]-> get local variable: name='andrew_waitConditionValidated'
if $waitValidated == [TRUE]
gosub GoToWork:
break
else
$t = 'Task ' + $id + ' does not meet WaitForCargo conditions'
[THIS]-> set orders string sprintf: fmt= $t , null , null , null , null , null
continue
end
else if $wasSuccess == [FALSE]
$t = 'Task ' + $id + ' is not valid yet'
[THIS]-> set orders string sprintf: fmt= $t , null , null , null , null , null
continue
else
[THIS]-> set orders string sprintf: fmt= 'No valid jobs available' , null , null , null , null , null
gosub WaitAndRestart:
break
end
end
end
end
end
* Andrew - catch at end of job validation loop.
gosub WaitAndRestart:
endsub
GetTrueTarget:
if [THIS]-> get local variable: name='mayhem_jobInfo'
= [THIS]-> call script 'Lib.Gen.ColourShipName' : String='*da' Colour=null OnlySearchLastThreeForDigits=[FALSE] OnlyReturnString=[FALSE] Ship=[THIS]
* Check homebase thresholds (in #).
$threshold = table get $thresholds ( $ware )
if not $threshold
$max = [HOMEBASE]-> get max amount of ware $ware that can be stored in cargo bay
$export = 0
$import = $max
else
$export = $threshold[0]
$import = $threshold[1]
end
if ($task == 0 AND $sanctuaryStock < $import) OR ($task == 1 AND $sanctuaryStock >= $export)
* Valid homebase thresholds, now we check target thresholds and define valid targets.
$validTargets = array alloc: size=0
if $targetType == 'Sector'
* Thresholds are in %.
$allStations = $target-> get station array from sector
for each $station in array $allStations
$stationOwner = $station-> get owner race
do if $stationOwner != [Player]
continue
$isSanctuary = $station-> is of type {*** UNDEFINED *** (SS_DOCK_SANCTUARY)}
$isStarliner = $station-> is of type {Argon OTAS Starliner Equipment Dock}
$isMcCallum = $station-> is of type {Argon OTAS McCallum Equipment Dock}
do if $isSanctuary OR $isStarliner OR $isMcCallum
continue
$isProduct = $station-> uses ware $ware as product
$isResource = $station-> uses ware $ware as primary resource
skip if $isResource
$isResource = $station-> uses ware $ware as secondary resource
do if ($task == 0 AND !$isProduct) OR ($task == 1 AND !$isResource)
continue
$targetStock = $station-> get ware storage percentage: ware=$ware
$targetExport = $station-> get factory export threshold
$targetImport = $station-> get factory import threshold
do if ($task == 0 AND $targetStock >= $targetExport) OR ($task == 1 AND $targetStock <= $targetImport)
append $station to array $validTargets
end
else if $targetType == 'Sanctuary'
* Thresholds are in #.
$targetLogistics = $target-> get local variable: name='mayhem_logistics'
$targetThresholds = table get $targetLogistics ( 'thresholds' )
$targetThreshold = table get $targetThresholds ( $ware )
if not $targetThreshold
$max = $target-> get max amount of ware $ware that can be stored in cargo bay
$targetExport = 0
$targetImport = $max
else
$targetExport = $targetThreshold[0]
$targetImport = $targetThreshold[1]
end
$targetStock = $target-> get amount of ware $ware in cargo bay
do if ($task == 0 AND $targetStock > $targetExport) OR ($task == 1 AND $targetStock < $targetImport)
append $target to array $validTargets
else if $targetType == 'Trade'
if $task == 0
$t = 'Looking for ' + $ware + ' sellers'
else if $task == 1
$t = 'Looking for ' + $ware + ' buyers'
end
[THIS]-> set orders string sprintf: fmt= $t , null , null , null , null , null
= wait 3000 ms
$hasBestBuy = [THIS]-> get amount of ware {Best Buys Locator} in cargo bay
$hasBestSell = [THIS]-> get amount of ware {Best Selling Price Locator} in cargo bay
$maxJumps = [HOMEBASE]-> get max trade jumps
do if $maxJumps > 0
$maxJumps = $maxJumps - 1
* Bug? Saw a ship going to 11 jumps when HOMEBASE has specified 10 jumps
$allSectors = [HOMEBASE]-> find all sectors within $maxJumps jumps: Only known sectors=[TRUE]
$blacklist = get global variable: name='mayhem_DABlacklist'
for each $sector in array $allSectors
do if table get $blacklist ( $sector )
continue
$allStations = $sector-> get station array from sector
for each $station in array $allStations
skip if $station-> is station sector PPP: for race= [Player]
continue
$stationOwner = $station-> get owner race
do if $stationOwner == [Player]
continue
$canDock = [THIS]-> is docking allowed at $station
skip if $canDock
continue
$isDock = $station-> is of class [Dock]
$canBuy = [THIS]-> can buy ware $ware at station $station
$isProduct = $station-> uses ware $ware as product
$isResource = $station-> uses ware $ware as primary resource
skip if $isResource
$isResource = $station-> uses ware $ware as secondary resource
if ($task == 0 AND $canBuy AND $isProduct) OR ($task == 1 AND !$isDock AND $isResource) OR ($task == 1 AND $isDock AND $isProduct)
$warePrice = $station-> get price of ware $ware
do if ($task == 0 AND $warePrice <= $tradePrice) OR ($task == 1 AND $warePrice >= $tradePrice)
append $station to array $validTargets
end
end
if ($task == 0 AND $hasBestBuy) OR ($task == 1 AND $hasBestSell)
= wait 50 ms
else
= wait randomly from 200 to 600 ms
end
end
end
* Sort by wares availability.
$sort = array alloc: size=0
$data = array alloc: size=0
for each $target in array $validTargets
if $task == 0
* Acquire
$qty = $target-> get amount of ware $ware in cargo bay
else if $task == 1
* Distribute
$qty = $target-> get free amount of ware $ware in cargo bay
end
append $qty to array $sort
append $target to array $data
end
$validTargets = sort array: data=$data sort values=$sort
$validTargets.length = size of array $validTargets
if $validTargets.length
* Valid target thresholds, we check pause state.
for each $target in array $validTargets using counter $index
do if $target-> get station pause traders
remove element from array $validTargets at index $index
end
$validTargets.length = size of array $validTargets
if $validTargets.length
* Valid targets, we synchronize with other ships on the job and select the final target (trueTarget).
$trueTarget = null
if $task == 0
* Here we need to acquire, so we check buddies destination and how much product they can store before making a decision.
$i = 0
for each $target in array $validTargets
$availableWares = $target-> get amount of ware $ware in cargo bay
$buddies = [HOMEBASE]-> call script 'Mayhem.GetShipsOnJobForDestination' : id=$id destination=$target returnLength=[FALSE]
$buddiesNeededWares = 0
for each $buddy in array $buddies
do if $buddy == [THIS]
continue
$buddyStoreableWares = $buddy-> get max amount of ware $ware that can be stored in cargo bay
if $cargoLoad
$buddyNeededWares = $cargoLoadQty
do if $buddyNeededWares > $buddyStoreableWares
$buddyNeededWares = $buddyStoreableWares
else
$buddyNeededWares = $buddyStoreableWares
end
$buddiesNeededWares = $buddiesNeededWares + $buddyNeededWares
end
$availableWares = $availableWares - $buddiesNeededWares
* We select the target that has the maximum availability.
if $availableWares > $i
$i = $availableWares
$trueTarget = $target
end
= wait 1 ms
end
else if $task == 1
* Here we need to distribute, so we just look at number of ships per destination and go where the less buddies are going.
$buddies = [HOMEBASE]-> call script 'Mayhem.GetShipsOnJob' : id=$id returnLength=[FALSE]
$buddiesDestinations = table alloc
for each $buddy in array $buddies
do if $buddy == [THIS]
continue
$destination = $buddy-> get destination
if $destination-> exists
$i = table get $buddiesDestinations ( $destination )
if $i
inc $i
else
$i = 1
end
table set $buddiesDestinations ( $destination ) = $i
end
end
$i = 99
for each $target in array $validTargets
$j = table get $buddiesDestinations ( $target )
if $i > $j
$i = $j
$trueTarget = $target
else if $j == null
$trueTarget = $target
break
end
end
end
if $trueTarget-> exists
[THIS]-> set local variable: name='andrew_foundLegitJob' value=[TRUE]
else
if $task == 0
$t = 'No source found'
else if $task == 1
$t = 'No destination found'
end
[THIS]-> set orders string sprintf: fmt= $t , null , null , null , null , null
[THIS]-> set local variable: name='andrew_foundLegitJob' value=[FALSE]
end
else
* All targets are paused.
if $task == 0
$t = 'Waiting for source to unpause'
else if $task == 1
$t = 'Waiting for destination to unpause'
end
[THIS]-> set orders string sprintf: fmt= $t , null , null , null , null , null
[THIS]-> set local variable: name='andrew_foundLegitJob' value=[FALSE]
end
else
* Invalid target thresholds or no trading partner.
if $task == 0
if $targetType == 'Trade'
$t = 'No ' + $ware + ' seller found'
[THIS]-> set orders string sprintf: fmt= $t , null , null , null , null , null
else
[THIS]-> set orders string sprintf: fmt= 'Waiting for source export threshold' , null , null , null , null , null
end
else if $task == 1
if $targetType == 'Trade'
$t = 'No ' + $ware + ' buyer found'
[THIS]-> set orders string sprintf: fmt= $t , null , null , null , null , null
else
[THIS]-> set orders string sprintf: fmt= 'Waiting for destination import threshold' , null , null , null , null , null
end
end
[THIS]-> set local variable: name='andrew_foundLegitJob' value=[FALSE]
end
else
* Invalid homebase thresholds.
if $task == 0
[THIS]-> set orders string sprintf: fmt= 'Waiting for homebase import threshold' , null , null , null , null , null
else if $task == 1
[THIS]-> set orders string sprintf: fmt= 'Waiting for homebase export threshold' , null , null , null , null , null
end
[THIS]-> set local variable: name='andrew_foundLegitJob' value=[FALSE]
end
else
* No job found.
[THIS]-> set orders string sprintf: fmt= 'Waiting for a job' , null , null , null , null , null
[THIS]-> set local variable: name='andrew_foundLegitJob' value=null
end
endsub
GetNeededWares:
$maxStoreableWares = [THIS]-> get max amount of ware $ware that can be stored in cargo bay
$sanctuaryStock = [HOMEBASE]-> get amount of ware $ware in cargo bay
$sanctuaryThreshold = table get $job ( 'sanctuaryThreshold' )
$cargoLoad = table get $job ( 'cargoLoad' )
$cargoLoadQty = table get $job ( 'cargoLoadQty' )
$waitCargo = table get $job ( 'waitCargo' )
* We first check the cargo load setting.
if $cargoLoad
$neededWares = $cargoLoadQty
do if $neededWares > $maxStoreableWares
$neededWares = $maxStoreableWares
else
$neededWares = $maxStoreableWares
end
* Then we check how much product we have in Sanctuary, compared to the required threshold. UPDATE: we actually don`t do that, the cargo setting should be enough.
* if $task == 0
* * Acquire
* $sanctuaryNeeds = $sanctuaryThreshold - $sanctuaryStock
* do if $neededWares > $sanctuaryNeeds
* $neededWares = $sanctuaryNeeds
* do if $cargoLoad AND $cargoLoadQty < $neededWares
* $neededWares = $cargoLoadQty
* do if $sanctuaryStock > $sanctuaryThreshold
* $neededWares = 0
* else if $task == 1
* * Distribute
* $remainder = $sanctuaryStock - $neededWares
* do if $remainder < $sanctuaryThreshold
* $neededWares = $sanctuaryStock - $sanctuaryThreshold
* do if $cargoLoad AND $cargoLoadQty < $neededWares
* $neededWares = $cargoLoadQty
* do if $sanctuaryStock < $sanctuaryThreshold
* $neededWares = 0
* end
* do if $neededWares < 0
* $neededWares = 0
* Recheck some stuff here to make sure our job is still valid.
if $task == 0
do if $sanctuaryStock > $sanctuaryThreshold
$neededWares = 0
else if $task == 1
do if $sanctuaryStock < $sanctuaryThreshold
$neededWares = 0
end
endsub
* A pre-job-start validation function to satisfy the condition of $waitCargo (in my opinion)
* A DA should only begin a WaitForCargo Acquire run when the source location can meet the WaitForCargo requirement , else it should consider the next job
* Similarly, a DA should only begin a WaitForCargo Distribute run when the destination location(s) will accept the Cargo without the DA needing to wait
* If this condition changes while in flight, the worker will wait. (maybe not the best behaviour....?)
AndrewValidateWaitingForCargoCondition:
[THIS]-> set local variable: name='andrew_waitConditionValidated' value=[TRUE]
if $task == 1
gosub GetNeededWares:
if $waitCargo AND $sanctuaryStock < $neededWares
[THIS]-> set local variable: name='andrew_waitConditionValidated' value=[FALSE]
end
end
if $task == 0
* Acquire
gosub GetNeededWares:
$targetStock = $trueTarget-> get amount of ware $ware in cargo bay
if $waitCargo AND $targetStock < $neededWares
[THIS]-> set local variable: name='andrew_waitConditionValidated' value=[FALSE]
end
end
endsub
GoToWork:
if $task == 1
gosub GetNeededWares:
while $waitCargo AND $sanctuaryStock < $neededWares
[THIS]-> set orders string sprintf: fmt= 'Waiting for cargo' , null , null , null , null , null
= wait randomly from 20000 to 30000 ms
gosub GetNeededWares:
$waitCargo = table get $job ( 'waitCargo' )
end
do if $neededWares == 0
* goto label Restart:
gosub Reboot:
= [THIS]-> load $neededWares units of $ware
end
= [THIS]-> call script 'Lib.Cmd.Refuel.Pre' : Destination=$trueTarget MininumJumpRange=0
if $task == 0
$t = 'Acquiring %s'
else if $task == 1
$t = 'Distributing %s'
end
[THIS]-> set orders string sprintf: fmt= $t , $ware , null , null , null , null
[THIS]-> set destination to $trueTarget
= [THIS]-> call script '!move.movetostation' : targetstation=$trueTarget
[THIS]-> set destination to null
= wait 1 ms
if $task == 0
* Acquire
gosub GetNeededWares:
$targetStock = $trueTarget-> get amount of ware $ware in cargo bay
while $waitCargo AND $targetStock < $neededWares
[THIS]-> set orders string sprintf: fmt= 'Waiting for cargo' , null , null , null , null , null
= wait randomly from 20000 to 30000 ms
gosub GetNeededWares:
$waitCargo = table get $job ( 'waitCargo' )
$targetStock = $trueTarget-> get amount of ware $ware in cargo bay
end
do if $neededWares == 0
* goto label Restart:
gosub Reboot:
if $targetType == 'Trade'
$availableWares = [THIS]-> buy $neededWares units of $ware
else
$availableWares = [THIS]-> load $neededWares units of $ware
end
if $availableWares
= [THIS]-> call script 'Lib.Cmd.Refuel.Pre' : Destination=[HOMEBASE] MininumJumpRange=0
$t = 'Returning home with %s'
[THIS]-> set orders string sprintf: fmt= $t , $ware , null , null , null , null
[THIS]-> set destination to [HOMEBASE]
= [THIS]-> call script '!move.movetostation' : targetstation=[HOMEBASE]
[THIS]-> set destination to null
= wait 1 ms
= [THIS]-> unload $availableWares units of $ware
else if $trueTarget-> exists
if $targetType == 'Trade'
$t = [THIS] + ' was unable to buy ' + $ware + ': insufficient homebase funds'
else
$t = [THIS] + ' was unable to load ' + $ware + ' from ' + $trueTarget
end
display info box: text= $t, icon= 29, timeout= 15000, fadeout= 2000
write to player logbook $t
end
else if $task == 1
* Distribute
if $targetType == 'Trade'
= [THIS]-> sell $neededWares units of $ware
else
= [THIS]-> unload $neededWares units of $ware
end
do if $ware == {Energy Cells}
gosub QuickRefuel:
end
[THIS]-> set local variable: name='mayhem_jobInfo' value=null
* goto label Restart:
gosub Reboot:
endsub
QuickRefuel:
$ecell = [DOCKEDAT]-> get amount of ware {Energy Cells} in cargo bay
$fuel = [THIS]-> get resupply fuel required
do if $fuel > 0 AND $ecell >= $fuel
= [THIS]-> load $fuel units of {Energy Cells}
endsub
WaitAndRestart:
= wait 20000 ms
* *goto label Restart:
gosub Reboot:
endsub
Reboot:
$scriptName = get script name
$taskID = get task ID
START [NULL]-> call script 'Lib.Gen.RunScriptWhenFinished' : ScriptName=$scriptName TaskWatch=$taskID TaskRun=$taskID ObjectWatch=[THIS] ObjectRun=[THIS] arg1=null arg2=null arg3=null arg4=null arg5=null
return null
endsub
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment