DaleStan wrote:How difficult would it be to fix that by defining that the callbacks are called according to the aircraft state, not according to the <heading> in the FTA info?
It turns out that I didn't look closely enough. The state callbacks *are* called based on aircraft state, not FTA heading. Never mind.
DaleStan wrote:1) It still doesn't define terminal-group selection, but I've asked Darkvater about how that works. Now I need to either (a) wait for an answer, (b) dig around in the source and try to figure it out for myself, or (c) add a callback, and basically ignore the system that Open currently uses.
/me went with b.
Bad Idea. Really Bad Idea.
When I start studying source, I'm not often happy until I understand it.
Occasionally I discover that I was happier not understanding it.
This is one of those cases.
I'm not sure whether I should be scared that I understand it, scared that it works, or scared that someone else can produce code as convoluted as mine. (That's a compliment, Darkvater, in case it wasn't clear.)
Format version 2: Additions and changes are marked in bold, removals are marked in red
Prop 16 contains the feature of the vehicles that will use this station, default is 00. (Currently only 00 and 03 are supported)
Prop 17 defines airport movement data and the state machine. It is variable-lengthed and formatted as follows:
<num-pos> is a byte.
<pos-data> is variable-length and repeated <num-data> times.
The <pos-data> corresponding to the hangar(s), if any, must be the first entries in the <pos-data> array, and must correspond to the hangar locations given in prop 19.
It consists of:
<X> <Y> <Z>
<block> (<next-info>)* [FF]
<X> and <Y> are words, interpreted as signed integers. They are the X and Y locations of this postion relative to the north corner of the airport. (A tile is 16 (10h) units in each direction.)
<Z> is a byte, as an unsigned integer, giving the height above the ground for this position. One landscaping level is eight units. Aircraft in flight ignore this setting. The default for heliports is 3C and for oil rigs is 36. This is intended to allow placing a helipad on top of a building while still allowing other things at ground level in the same airport.
<flags> is a word, formatted as follows:
The high nine bits are flags:
07 : Movement for current state (possibly) completed; process and update state.
: Do not clamp speed to taxiing limit.
: This is an airplane take-off location.
: Aircraft must wait several ticks prior to turning in this position.
: This is an airplane landing location.
: Force aircraft facing.
: Play the airplane brake noise when switching to this position.
: This is a helicopter take-off location.
: This is a helicopter landing location.
(bits 9..15 map to the AMED_* constants.)
If bit 12 is set, the low three bits specify the direction that the aircraft is turned to face upon reaching this position.
If both bits 1 and 3 are set, this is the point where airplanes enter this state machine.
If both bits 6 and 7 are set, this is the point where choppers enter this state machine.
<direction> is a byte, and ignored unless bit 4 of <flags> is set. If that bit is set, the aircraft is turned to face the specified direction.
<block> is a byte, indicating which block this position is a part of. Block FF
may have any number of aircraft in it at any one time; all others may have at most one at a time. If <block> is the controlling block for a single terminal or helipad, it must have the same value as the <heading> for going to that terminal/helipad. All other block values may be used in any way you desire.
<next-info> is three bytes, in one of the two following formats:
<heading> <check-block> <next>
<heading> is a byte.
If heading is in 00..3F, it specifies the number of the terminal this aircraft is going to.
If heading is in 40..7F, the low 6 bits specify the number of the helipad this chopper is going to.
(Yes, airports can have up to 64 each terminals and helicopter pads. This should be sufficient for most purposes.)
The following special values are also available:
80: HANGAR -- Aircraft is going to a hangar, or if at a hangar, enters it for servicing. (Next: TAKEOFF, HELITAKEOFF, TERMn, HELIPADn) 
81: TAKEOFF -- Airplane is headed for the runway for takeoff. (Next: STARTTAKEOFF)
82: STARTTAKEOFF -- Airplane is accellerating down the runway; (Next: ENDTAKEOFF)
83: ENDTAKEOFF -- The airplane is rising into the air. (Next: none; enters state machine of next airport, with state FLYING)
84: HELITAKEOFF -- Like TAKEOFF, but for choppers. (Next: HELIENDTAKEOFF)
: FLYING -- The aircraft is in the air, headed for its next order. (Next: LANDING, HELILANDING) 
: LANDING -- The airplane wants to land. (Next: ENDLANDING)
: ENDLANDING -- The airplane is rolling down the runway, and will come to a stop at the end. (Next: HANGAR, TERMn) 
: HELILANDING -- Like LANDING, but for choppers. (Next: HELIENDLANDING)
: HELIENDLANDING -- Like ENDLANDING, but for choppers. (Next: HANGAR, HELIPADn, TERMn if no helipads) 
-- Like ENDTAKEOFF, but for choppers. (Merge with ENDTAKEOFF?)
: ELSE -- All headings not previously mentioned (also used to mark the last <next-info> entry)
 These states have TERMn nexts, and should have terminal selection instructions if necessary.
 These states have HELIPADn nexts, and should have helipad selection instructions if necessary.
 These are currently machine exit states. To guard against additional states being added, <next-info> should be be FF FF <cur-pos>, that is "Always return here."
 No plane will ever query the state machine in the FLYING state; it will update to LANDING or HELILANDING first, and return to FLYING if it did not find an acceptable landing location.
2) <type> <check-block> <group> (Select terminal/helipad from group)
<type> is a byte, either FE (terminal selection) or FD (helipad selection)
The aircraft needs to know what terminal to go to. If <check-block> is clear, select the first free terminal from <group> (terminals are assigned to groups by prop 1A), and then return to this position with the selected heading. If <check-block> is occupied, or no free terminals exist in <group>, continue to the next terminal selection, or wait in this position if no more selections exist.
These may be specified anywhere in the <next-info> list.
These entries are required for terminal selection on HANGAR and *ENDLANDING positions if this airport has multiple groups, and are ignored otherwise. The *ENDLANDINGs should contain <*ENDLANDING> FF <self-pos> entries to keep the state machine here until it wakes up to the fact that it needs to select a terminal.
Prop 18 functions as prop 0A and 0F, but copies prop 17 instead.
Prop 19 sets the hangar postion(s). It consists of a byte counting the number of hangars, and then that many <X> <Y> pairs (both bytes, as unsigned integers) giving the (X,Y) offset of each hangar from the north corner of the airport.
Props 1A and 1B
set the number of terminals and helipads in each terminal/helipad group, respectively:
<num-in-group> is a byte, and is repeated until a 00 is encountered.
The sum of all <num-in-group> for each property must not exceed 64.
The <heading>s 00..7F (in prop 17) are assigned by these properties; 00/40 to the first item in the first group, 01/41 to the next item in the first group or the first item in the next group, &c.
is a byte which sets the airport type (small/large/heliport) for the purposes of LA build permissions, crash probablilty, and vehicle variable 44. Oil rig (03) exists internally, but may not be set by .grf files.
sets the types of aircraft that can land here:
00 : airplanes only
01 : all (default)
02 : choppers only
Prop 1E is two bytes; the first being the entry position for airplanes, and the second being the entry position for choppers. Must be set properly for both types, even if one type cannot land here. (This airport could be a replacement for an airport where that type could land.)
Prop 1F sets which tiles are animated:
<num-animated-tiles> (<X> <Y>)...
The tile at each (<X>,<Y>) is redrawn every tick. Callback 14 is also called to determine which sprite arrangement to use for this tile.
Properties 08, 09, 0A, 0B, 10, 12, and 13 function as for rail stations, except that bit 1 of prop 0B must be set.
Properties 0C, 0D 0E, 0F, 11, and 14 are meaningless (and ignored) in the context of airports.
Callback 13 works as for rail stations.
Callback 14 works as for rail stations, but may also return 100h to indicate "Build no tile here."
Callback 3C (no action 0 bit) is called whenever a plane with a set minimum-runway-length wants to switch to a STARTLANDING or TAKEOFF
position, and whenever a plane is given orders to this airport (assuming it passes prop 1C).
Variable 10 contains the position that the plane wishes to enter, or FFFFFFFF if an order was added.
The low byte of the return contains the length of this runway (ignored if var 10 is FFFFFFFF), and the high byte contains the length of the longest runway at this airport.
If the plane is in the air and it cannot land, it circles. If the plane is on the ground and it cannot take off, it stops.
Actions 1..3 work as for rail stations.
Action 4 works as for rail stations for C5xx IDs, and possibly for the C4xx IDs.
The third byte of vehicle variable 44 will have at least the following distinct (and airport-independent) values:
- In hangar
- On a pad
- Taking off
- In flight
The high byte of vehicle variable 44 will contain the <Z> value for the current position.
Example: the Country Airport's prop 17 could read as follows:
Code: Select all
17 17 //Prop 17, 17h locations
35 00 03 00 00 83 10 FF // 00 In hangar
// Terminal and pad selection instructions would appear here, if necessary.
FF FF 01 // Always go to 01
35 00 1B 00 00 00 00 09 // 01 Taxi to right outside depot
80 FF 00 // hangar; go to 00
00 00 02 // Terminal 0; supress check of block 00 and go to 02
01 FF 04 // Terminal 1; go to 04
84 FF 13 // HELITAKEOFF; go to 13
FF FF 06 // ELSE; go to 06
20 00 17 00 00 87 10 00 // 02 Terminal 0
FF FF 01 // Always go to 01
0A 00 17 00 00 87 10 01 // 03 Terminal 1
FF FF 05 // Always go to 05
2B 00 25 00 00 00 00 09 // 04 Going towards terminal 2
01 FF 05 // Terminal 1; go to 05
80 FF 01 // Hangar; go to 01
81 FF 06 // Takeoff; go to 06
FF FF 01 // ELSE (Heli takeoff) go to 01
18 00 25 00 00 00 00 09 // 05 Going towards terminal 2
01 01 03 // Terminal 1; supress check of block 01 and go to 03
FF FF 04 // ELSE go to 04
35 00 25 00 00 00 00 09 // 06 Going for takeoff
FF FF 07
3D 00 28 00 00 81 10 09 // 07 Taxi to start of runway (takeoff)
FF FF 08
03 00 28 00 00 80 01 FF // 08 Accelerate to end of runway
FF FF 09
B1 FE 28 00 00 80 03 FF // 09 Take off
FF FF 09 // ignored; the aircraft has left this state machine
B1 00 28 00 00 80 05 FF // 0A Fly to landing position in air
85 FF 0B // Landing; go to 0B
87 FF 14 // heli-landing; go to 14
FF FF 0F // Else; go to 0F
38 00 28 00 00 80 09 09 // 0B Going down for land
FF FF 0C
03 00 28 00 00 00 21 09 // 0C Just landed, brake until end of runway
FF FF 0D
07 00 28 00 00 80 00 09 // 0D Just landed, turn around and taxi 1 square
// Terminal selection instructions would appear here, if necessary.
01 FF 05 // Terminal 1
FF FF 0E
35 00 28 00 00 00 00 09 // 0E Taxi from runway to crossing
FF FF 01
E1 FE C1 00 00 00 05 FF // 0F Fly around waiting for a landing spot (north-east)
FF FF 10
01 00 01 00 00 00 05 FF // 10 Fly around waiting for a landing spot (north-west)
FF FF 11
01 01 01 00 00 00 05 FF // 11 Fly around waiting for a landing spot (south-west)
FF FF 12
11 01 31 00 00 00 05 FF // 12 Fly around waiting for a landing spot (south)
FF FF 0A
2C 00 25 00 00 80 40 FF // 13 Helicopter takeoff
FF FF 16 // This is changed, due to the new HELIENDTAKEOFF state
2C 00 28 00 00 80 05 09 // 14 In position above landing spot helicopter
FF FF 15
2C 00 28 00 00 80 00 09 // 15 Helicopter landing
// Terminal or pad selection instructions would appear here, if necessary.
// Terminal selection instructions would be ignored here if any helipads exist.
FF FF 01
2C 00 25 00 00 80 05 FF // 16 Heli end takeoff
FF FF 16 //Ignored; the heli has left the state machine.