(info) Probing carrier docking slots via script APIs

The place to discuss scripting and game modifications for X³: Terran Conflict and X³: Albion Prelude.

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

Post Reply
Shimrod
Posts: 907
Joined: Tue, 18. Feb 03, 01:43
x4

(info) Probing carrier docking slots via script APIs

Post by Shimrod » Sun, 6. Apr 14, 20:31

I thought I'd share some data I gathered from script APIs in probing carrier capabilities. This is on AP with XRM.

<RetVar/IF> <RefObj> has a free ship dock port: ship subtype = <Value>
- Returns null if docking bays are full
- Sensitive to class of ship, e.g. HCP docks M5 but not M3.
- <value> can be a ship instance or ship type (but not class)
- <RefObj> can be a station or ship
- BUG: reports a false positive if docking bays are filled with ships that were created in a docked state

<RetVar><RefObj> is docking allowed at <Var/Ship/Station>
- Returns null if docking bays are full
- Ignores class of ship
- Refobj can be ship type, ship instance or object class.

<RetVar/IF> <RefObj> is docking possible of <Value>
- Ignores whether docking bays are full
- Sensitive to class of ship, e.g. HCP docks M5 but not M3.
- <value> can be a ship instance (not ship type or class)

Reference

Script

Code: Select all

$Carrier.Bays = $Carrier-> get dock bay size
$Carrier.Type = datatype[$Carrier]
$Docked = $Carrier->get ship array from sector/ship/station
$Docked.Count = size of array $Docked
$Carrier.Bays.Free = $Carrier.Bays - $Docked.Count

$m2.class = [M2]
$m3.class = [M3]
$m4.class = [M4]
$m5.class = [M5]
$m2.ware = {Argon Titan}
$m3.ware = {Argon Nova}
$m4.ware = {Argon Buster}
$m5.ware = {Argon Discoverer}
$m2.ship = create ship: type=$m2.ware owner=[Neutral Race] addto=null x=0 y=0 z=0
$m3.ship = create ship: type=$m3.ware owner=[Neutral Race] addto=null x=0 y=0 z=0
$m4.ship = create ship: type=$m4.ware owner=[Neutral Race] addto=null x=0 y=0 z=0
$m5.ship = create ship: type=$m5.ware owner=[Neutral Race] addto=null x=0 y=0 z=0

$m2.ware.free = $Carrier-> has a free ship dock port: ship subtype = $m2.ware
$m3.ware.free = $Carrier-> has a free ship dock port: ship subtype = $m3.ware
$m4.ware.free = $Carrier-> has a free ship dock port: ship subtype = $m4.ware
$m5.ware.free = $Carrier-> has a free ship dock port: ship subtype = $m5.ware

$m2.ship.free = $Carrier-> has a free ship dock port: ship subtype = $m2.ship
$m3.ship.free = $Carrier-> has a free ship dock port: ship subtype = $m3.ship
$m4.ship.free = $Carrier-> has a free ship dock port: ship subtype = $m4.ship
$m5.ship.free = $Carrier-> has a free ship dock port: ship subtype = $m5.ship

$m2.class.free = $Carrier-> has a free ship dock port: ship subtype = $m2.class
$m3.class.free = $Carrier-> has a free ship dock port: ship subtype = $m3.class
$m4.class.free = $Carrier-> has a free ship dock port: ship subtype = $m4.class
$m5.class.free = $Carrier-> has a free ship dock port: ship subtype = $m5.class

$m2.ware.allowed = $m2.ware-> is docking allowed at $Carrier
$m3.ware.allowed = $m3.ware-> is docking allowed at $Carrier
$m4.ware.allowed = $m4.ware-> is docking allowed at $Carrier
$m5.ware.allowed = $m5.ware-> is docking allowed at $Carrier

$m2.ship.allowed = $m2.ship-> is docking allowed at $Carrier
$m3.ship.allowed = $m3.ship-> is docking allowed at $Carrier
$m4.ship.allowed = $m4.ship-> is docking allowed at $Carrier
$m5.ship.allowed = $m5.ship-> is docking allowed at $Carrier

$m2.class.allowed = $m2.class-> is docking allowed at $Carrier
$m3.class.allowed = $m3.class-> is docking allowed at $Carrier
$m4.class.allowed = $m4.class-> is docking allowed at $Carrier
$m5.class.allowed = $m5.class-> is docking allowed at $Carrier

$m2.ware.possible = $Carrier-> is docking possible of $m2.ware
$m3.ware.possible = $Carrier-> is docking possible of $m3.ware
$m4.ware.possible = $Carrier-> is docking possible of $m4.ware
$m5.ware.possible = $Carrier-> is docking possible of $m5.ware

$m2.ship.possible = $Carrier-> is docking possible of $m2.ship
$m3.ship.possible = $Carrier-> is docking possible of $m3.ship
$m4.ship.possible = $Carrier-> is docking possible of $m4.ship
$m5.ship.possible = $Carrier-> is docking possible of $m5.ship

$m2.class.possible = $Carrier-> is docking possible of $m2.class
$m3.class.possible = $Carrier-> is docking possible of $m3.class
$m4.class.possible = $Carrier-> is docking possible of $m4.class
$m5.class.possible = $Carrier-> is docking possible of $m5.class

$m2.ship-> destruct: show no explosion=1
$m3.ship-> destruct: show no explosion=1
$m4.ship-> destruct: show no explosion=1
$m5.ship-> destruct: show no explosion=1

write to log file 1234 append=1 value='-----------------------------------------------------------'
write to log file 1234 append=1 printf: fmt='Carrier=%s, Type=%s, Bays.Total=%s, Bays.Free=%s', $Carrier, $Carrier.Type, $Carrier.Bays, $Carrier.Bays.Free, null
write to log file 1234 append=1 printf: fmt='Free dock port (ware): m2=%s, m3=%s, m4=%s, m5=%s', $m2.ware.free, $m3.ware.free, $m4.ware.free, $m5.ware.free, null
write to log file 1234 append=1 printf: fmt='Free dock port (ship): m2=%s, m3=%s, m4=%s, m5=%s', $m2.ship.free, $m3.ship.free, $m4.ship.free, $m5.ship.free, null
write to log file 1234 append=1 printf: fmt='Free dock port (class): m2=%s, m3=%s, m4=%s, m5=%s', $m2.class.free, $m3.class.free, $m4.class.free, $m5.class.free, null
write to log file 1234 append=1 printf: fmt='Docking allowed (ware): m2=%s, m3=%s, m4=%s, m5=%s', $m2.ware.allowed, $m3.ware.allowed, $m4.ware.allowed, $m5.ware.allowed, null
write to log file 1234 append=1 printf: fmt='Docking allowed (ship): m2=%s, m3=%s, m4=%s, m5=%s', $m2.ship.allowed, $m3.ship.allowed, $m4.ship.allowed, $m5.ship.allowed, null
write to log file 1234 append=1 printf: fmt='Docking allowed (class): m2=%s, m3=%s, m4=%s, m5=%s', $m2.class.allowed, $m3.class.allowed, $m4.class.allowed, $m5.class.allowed, null
write to log file 1234 append=1 printf: fmt='Docking possible (ware): m2=%s, m3=%s, m4=%s, m5=%s', $m2.ware.possible, $m3.ware.possible, $m4.ware.possible, $m5.ware.possible, null
write to log file 1234 append=1 printf: fmt='Docking possible (ship): m2=%s, m3=%s, m4=%s, m5=%s', $m2.ship.possible, $m3.ship.possible, $m4.ship.possible, $m5.ship.possible, null
write to log file 1234 append=1 printf: fmt='Docking possible (class): m2=%s, m3=%s, m4=%s, m5=%s', $m2.class.possible, $m3.class.possible, $m4.class.possible, $m5.class.possible, null

return null
Output

Code: Select all

-----------------------------------------------------------
Carrier=Tractor Beam Factory Alpha(Prophecy Fulfilled), Type=DATATYPE_STATION, Bays.Total=5, Bays.Free=5
Free dock port (ware): m2=0, m3=1, m4=1, m5=1
Free dock port (ship): m2=0, m3=1, m4=1, m5=1
Free dock port (class): m2=0, m3=0, m4=0, m5=0
Docking allowed (ware): m2=1, m3=1, m4=1, m5=1
Docking allowed (ship): m2=1, m3=1, m4=1, m5=1
Docking allowed (class): m2=1, m3=1, m4=1, m5=1
Docking possible (ware): m2=null, m3=null, m4=null, m5=null
Docking possible (ship): m2=null, m3=1, m4=1, m5=1
Docking possible (class): m2=null, m3=null, m4=null, m5=null
-----------------------------------------------------------
Carrier=Duke's Shipyard(Duke's Buccaneers Headquarters), Type=DATATYPE_STATION, Bays.Total=11, Bays.Free=11
Free dock port (ware): m2=1, m3=1, m4=1, m5=1
Free dock port (ship): m2=1, m3=1, m4=1, m5=1
Free dock port (class): m2=1, m3=1, m4=1, m5=1
Docking allowed (ware): m2=1, m3=1, m4=1, m5=1
Docking allowed (ship): m2=1, m3=1, m4=1, m5=1
Docking allowed (class): m2=1, m3=1, m4=1, m5=1
Docking possible (ware): m2=1, m3=1, m4=1, m5=1
Docking possible (ship): m2=1, m3=1, m4=1, m5=1
Docking possible (class): m2=1, m3=1, m4=1, m5=1
-----------------------------------------------------------
Carrier=Heavy Centaur Prototype, Type=DATATYPE_WARE, Bays.Total=0, Bays.Free=0
Free dock port (ware): m2=null, m3=null, m4=null, m5=null
Free dock port (ship): m2=null, m3=null, m4=null, m5=null
Free dock port (class): m2=null, m3=null, m4=null, m5=null
Docking allowed (ware): m2=null, m3=null, m4=null, m5=null
Docking allowed (ship): m2=null, m3=null, m4=null, m5=null
Docking allowed (class): m2=null, m3=null, m4=null, m5=null
Docking possible (ware): m2=null, m3=null, m4=null, m5=null
Docking possible (ship): m2=null, m3=null, m4=null, m5=null
Docking possible (class): m2=null, m3=null, m4=null, m5=null
-----------------------------------------------------------
********* M5 created in docked state *******
Carrier=Your Heavy Centaur Prototype, Type=DATATYPE_SHIP, Bays.Total=1, Bays.Free=0
Free dock port (ware): m2=0, m3=0, m4=0, m5=1    <-- BUG
Free dock port (ship): m2=0, m3=0, m4=0, m5=1
Free dock port (class): m2=0, m3=0, m4=0, m5=0
Docking allowed (ware): m2=null, m3=null, m4=null, m5=null
Docking allowed (ship): m2=null, m3=null, m4=null, m5=null
Docking allowed (class): m2=null, m3=null, m4=null, m5=null
Docking possible (ware): m2=null, m3=null, m4=null, m5=null
Docking possible (ship): m2=null, m3=null, m4=null, m5=1
Docking possible (class): m2=null, m3=null, m4=null, m5=null
-----------------------------------------------------------
********* M5 was docked manually *******
Carrier=Your Heavy Centaur Prototype, Type=DATATYPE_SHIP, Bays.Total=1, Bays.Free=0
Free dock port (ware): m2=0, m3=0, m4=0, m5=0
Free dock port (ship): m2=0, m3=0, m4=0, m5=0
Free dock port (class): m2=0, m3=0, m4=0, m5=0
Docking allowed (ware): m2=null, m3=null, m4=null, m5=null
Docking allowed (ship): m2=null, m3=null, m4=null, m5=null
Docking allowed (class): m2=null, m3=null, m4=null, m5=null
Docking possible (ware): m2=null, m3=null, m4=null, m5=null
Docking possible (ship): m2=null, m3=null, m4=null, m5=1
Docking possible (class): m2=null, m3=null, m4=null, m5=null
-----------------------------------------------------------
Carrier=Your Heavy Centaur Prototype, Type=DATATYPE_SHIP, Bays.Total=1, Bays.Free=1
Free dock port (ware): m2=0, m3=0, m4=0, m5=1
Free dock port (ship): m2=0, m3=0, m4=0, m5=1
Free dock port (class): m2=0, m3=0, m4=0, m5=0
Docking allowed (ware): m2=1, m3=1, m4=1, m5=1
Docking allowed (ship): m2=1, m3=1, m4=1, m5=1
Docking allowed (class): m2=1, m3=1, m4=1, m5=1
Docking possible (ware): m2=null, m3=null, m4=null, m5=null
Docking possible (ship): m2=null, m3=null, m4=null, m5=1
Docking possible (class): m2=null, m3=null, m4=null, m5=null
-----------------------------------------------------------
Carrier=Paranid Military Zeus Y$X: K22 L0, Type=DATATYPE_SHIP, Bays.Total=43, Bays.Free=24
Free dock port (ware): m2=0, m3=1, m4=1, m5=1
Free dock port (ship): m2=0, m3=1, m4=1, m5=1
Free dock port (class): m2=0, m3=0, m4=0, m5=0
Docking allowed (ware): m2=1, m3=1, m4=1, m5=1
Docking allowed (ship): m2=1, m3=1, m4=1, m5=1
Docking allowed (class): m2=1, m3=1, m4=1, m5=1
Docking possible (ware): m2=null, m3=null, m4=null, m5=null
Docking possible (ship): m2=null, m3=1, m4=1, m5=1
Docking possible (class): m2=null, m3=null, m4=null, m5=null

User avatar
DrBullwinkle
Posts: 5715
Joined: Sat, 17. Dec 11, 01:44
x3tc

Post by DrBullwinkle » Sun, 6. Apr 14, 20:50

Thanks for sharing that, Shimrod.

Players periodically ask for a list of docking bay sizes on various ships (especially for major mods).

I think that probably requires walking through the list of carrier-class ships and trying different ship types (and counting how many can dock) to build the list.

"has a free ship dock port: ship subtype = <Value>" might be useful in that process.
  • (Well, all three commands might be useful... I just did not know about that one. :) )

Shimrod
Posts: 907
Joined: Tue, 18. Feb 03, 01:43
x4

Post by Shimrod » Sun, 6. Apr 14, 22:42

None of the APIs return the amount of dockable ships of a given class, so you'd need something like:
- Spawn carrier in sector null
- While has free dock port for that class
- Create a docked ship of that class
- Delete the docked ships, proceed to next class

But as 'has free ship dock port' is bugged with respected to spawned docked ships, this may not be possible unless you can do something like spawn the ship externally then use 'put into environment' to dock it without triggering the bug.

There's also a gotcha in that ships often allow for maximum 2 externally docked ships of a set of types { M6, TS } rather than 2 of each type.

User avatar
DrBullwinkle
Posts: 5715
Joined: Sat, 17. Dec 11, 01:44
x3tc

Post by DrBullwinkle » Sun, 6. Apr 14, 22:47

Shimrod wrote:you'd need something like ...
Exactly. :)

zanzal
Posts: 309
Joined: Sat, 15. Sep 12, 07:42
x3tc

Post by zanzal » Mon, 7. Apr 14, 02:26

I was obsessed with obtaining this information for my ship browser mod. No amount of programmatic brute force or clever usage of the API would get to work right. Even tried creating the ships outside putting them in afterwards etc. Even asked an experienced modder about it and couldn't get it to work using his approaches to the problem.

I eventually decided that there was a disconnect between the script engine API and the internal API used by the flight commands for docking. The internal flight commands respect docking limitations imposed by the models for external dock areas whereas the script API only checks the most basic parameters and works well only for ships with an internal fighter dock.

The only way IMO short of a fix by ES would be to simulate docking (preferrably out of sector) and store the results for later usage. For example, create a carrier, do the basic checks to see if it has a free docking port for the class you want to dock then if it does attempt to simulate docking via the flight commands. If the ship docks within X minutes then a docking port was available. If the ship flies around and doesn't dock then assume no docking port available for that class, try again with a lower class while docking ports available. It could take awhile to simulate the results but could store the results and only re-run the simulation if data from the api changes for the carrier ship subtype.

Nicoman35
Posts: 681
Joined: Thu, 17. Nov 05, 13:12
x3tc

Post by Nicoman35 » Mon, 7. Apr 14, 09:22

While doing parts of ADS RWE, I had the same problem. I was mostly anoyed by not being possible IS to dock M6 at extternal docking ports (XRM) using the docking computer.
OOS no problem, as the ships are set to the spot where the carrier is, then '<RetVar/IF><RefObj> fly to station <Var/Station>'
is called. That way M6 are docked correctly to external docks.

IS, '<RefObj> put into environment <RefObj>' is used to achieve this. The downside of this command is putting M6 an internal docking port. This way the command 'has a free ship dock port: ship subtype = <Value>' can be tricky sometimes.

In a touch of boldness, I wanted to correct this by reverse engeneering the game exe.
I gave up pretty fast, after I saw the PE assembler output of roughly 590.000 lines....

Code: Select all

SUB_L00401000:
  		mov	edx,[eax]
  		push	esi
  		mov	esi,ecx
  		mov	eax,edx
L00401007:
  		mov	cl,[esi]
  		mov	[edx],cl
  		add	esi,00000001h
  		add	edx,00000001h
  		test	cl,cl
  		jnz	L00401007
  		pop	esi
  		retn
        ...

Post Reply

Return to “X³: Terran Conflict / Albion Prelude - Scripts and Modding”