====== .UNI file ====== The .UNI file holds information about the units. ===== .UNI File Format ===== ==== Raw (compressed contents) ==== ^Field^Data Type^Width (in bytes)^Description^ |CompressedSize |Signed 32-bit integer|4|Size, in bytes, of the compressed data to follow (includes space for the NumUnits and UncompressedSize fields)| |NumUnits |Signed 16-bit integer|2|Number of unit records in the data that follows| |UncompressedSize|Signed 32-bit integer|4|Size, in bytes, of the data that follows, when it's uncompressed| |DATA|byte[]|(CompressedSize-6) bytes|[[falcon4:file_formats:cam_trn_tac:lzss_compression|LZSS-compressed]] binary data.| ==== Uncompressed contents of the DATA field ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |unitRecords[]|UnitRecord[NumUnits]| | |All| ===== Structures Used ===== ==== UnitRecord structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |unitType|signed 16-bit integer|2| subtract 100 from this value to find the index into the Falcon classtable records, for this unit |All| |Data[]| byte array| content and length depends on the type of unit defined in the classtable, at the index specified by (unitType -100), and the file version in-use. || All | For each unit record, you will need to retrieve the corresponding class table entry from the [[falcon4:file_formats:ct_file|class table file ]]in order to interpret the data that follows in that unit record's data buffer in the .UNI file. After retrieving a unit's classtable entry, read the vuClassData.classInfo[0] value, which will tell you the Domain (air=2, land=3, or sea=4) that this unit belongs to. Then, check the unit's classtable entry's vuClassData.classInfo[2] value, which will tell you the type of unit: Air domain: vuClassData.classInfo[2]=1 -- this is a Flight vuClassData.classInfo[2]=2 -- this is a Package vuClassData.classInfo[2]=3 -- this is a Squadron Land domain: vuClassData.classInfo[2]=1 -- this is a Battalion vuClassData.classInfo[2]=2 -- this is a Brigade Sea domain: vuClassData.classInfo[2]=1 -- this is a Task Force Once you know what type of unit it is, you can use the appropriate structure (Flight, Package, Squadron, Battalion, Brigade, or TaskForce) to interpret the data that follows the "unitType". Immediately following the data for that unit, is another "UnitType"/Data[] pair. This continues until you have read "NumUnits" records from the file. **Note: this information is valid for versions up to about version 71. Details for subsequent versions are currently not documented ** ==== Flight structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |id|VU_ID|8| |All| |entityType| unsigned 16-bit integer | 2| | All| |x| Signed 16-bit integer | 2| | All| |y| Signed 16-bit integer | 2| | All| |z| single-precision 32-bit floating point | 4| | >=70 | |spotTime| unsigned 32-bit integer | 4| | All | |spotted| signed 16-bit integer | 2| | All | |baseFlags | signed 16-bit integer | 2| | All | |owner | byte | 1| | All | |campId | signed 16-bit integer | 2| | All | |last_check| unsigned 32-bit integer| 4| | All| |roster| Signed 32-bit integer| 4| | All| |unit_flags| Signed 32-bit integer| 4| | All| |dest_x| Signed 16-bit integer| 2| | All| |dest_y| Signed 16-bit integer| 2| | All| |target_id|VU_ID|8| |All| |cargo_id|VU_ID|8| |> 1| |moved| byte| 1| | All| |losses| byte| 1| | All| |tactic| byte| 1| | All| |current_wp| unsigned 16-bit integer| 2| | > = 71| |current_wp| byte| 1| | < 71| |name_id| Signed 16-bit integer| 2| | All| |reinforcement| Signed 16-bit integer| 2| | All| |numWaypoints| unsigned 16-bit integer| 2| | > = 71| |numWaypoints| byte | 1| | < 71| |waypoints[]| Waypoint[numWaypoints]| | | All| |pos_z| single-precision 32-bit floating point | 4 | | All| |fuel_burnt| Signed 32-bit integer | 4 | if Version < 65, this value is present but is meaningless so zero it out | All| |last_move| unsigned 32-bit integer | 4 | | All| |last_combat| unsigned 32-bit integer | 4 | | All| |time_on_target| unsigned 32-bit integer | 4 | | All| |mission_over_time| unsigned 32-bit integer | 4 | | All| |mission_target| Signed 16-bit integer | 2 | | All| |use_loadout| byte | 1 | | 8 thru 23 | |loadout| LoadoutArray | | | 8 thru 23 | |weapon[]| array of Signed 16-bit integer * 16| 32| |< 18| |weapon[]| byte[16]| 16| | 18 thru 23| |weapons[]| byte[16]| 16| | 18 thru 23| |loadouts| byte | 1| | > = 24| |loadout[]| LoadoutStruct[loadouts] | | | > = 24| |mission| byte | 1 | | All | |old_mission| byte | 1 | | > 65 | |last_direction| byte | 1 | | All | |priority| byte | 1 | | All | |mission_id| byte | 1 | | All | |dummy| byte | 1 | | < 14 | |eval_flags| byte | 1 | | < 14 | |mission_context| byte | 1 | | > 65 | |package| VU_ID| 8 | | All | |squadron| VU_ID| 8 | | All | |requester| VU_ID| 8 | | > 65 | |slots[]| byte[4]| 4 | | All | |pilots[]| byte[4]| 4 | | All | |plane_stats[]| byte[4]| 4 | | All | |player_slots[]| byte[4]| 4 | | All | |last_player_slot| byte| 1 | | All | |callsign_id| byte| 1 | | All | |callsign_num| byte| 1 | | All | ==== Squadron structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |id|VU_ID|8| |All| |entityType| unsigned 16-bit integer | 2| | All| |x| Signed 16-bit integer | 2| | All| |y| Signed 16-bit integer | 2| | All| |z| single-precision 32-bit floating point | 4| | >=70 | |spotTime| unsigned 32-bit integer | 4| | All | |spotted| signed 16-bit integer | 2| | All | |baseFlags | signed 16-bit integer | 2| | All | |owner | byte | 1| | All | |campId | signed 16-bit integer | 2| | All | |last_check| unsigned 32-bit integer| 4| | All| |roster| Signed 32-bit integer| 4| | All| |unit_flags| Signed 32-bit integer| 4| | All| |dest_x| Signed 16-bit integer| 2| | All| |dest_y| Signed 16-bit integer| 2| | All| |target_id|VU_ID|8| |All| |cargo_id|VU_ID|8| |> 1| |moved| byte| 1| | All| |losses| byte| 1| | All| |tactic| byte| 1| | All| |current_wp| unsigned 16-bit integer| 2| | > = 71| |current_wp| byte| 1| | < 71| |name_id| Signed 16-bit integer| 2| | All| |reinforcement| Signed 16-bit integer| 2| | All| |numWaypoints| unsigned 16-bit integer| 2| | > = 71| |numWaypoints| byte | 1| | < 71| |waypoints[]| Waypoint[numWaypoints]| | | All| |fuel| Signed 32-bit integer|4 | | All| |specialty| byte|1 | | All| |stores[]| byte[200] |200 | | < 69| |stores[]| byte[220] |220 | | 69 thru 71 (inclusive)| |stores[]| byte[600] |600 | | > = 72| |pilots[]| Pilot[36] | | |< 29 | |pilots[]| Pilot[48] | | | > = 29 | |schedule[]| array of Signed 32-bit integer * 16 | 4 * 16 = 64 bytes | | All | |airbase_id| VU_ID| 8 | | All | |hot_spot| VU_ID| 8 | | All | |junk | VU_ID| 8 | | 6 thru 15 | |rating[] | byte[16]|16 | | All | |aa_kills | Signed 16-bit integer|2 | | All | |ag_kills | Signed 16-bit integer|2 | | All | |as_kills | Signed 16-bit integer|2 | | All | |an_kills | Signed 16-bit integer|2 | | All | |missions_flown | Signed 16-bit integer|2 | | All | |mission_score | Signed 16-bit integer|2 | | All | |total_losses | byte |1 | | All | |pilot_losses | byte |1 | | >= 9 | |squadron_patch | byte |1 | | < 45 | ==== Package structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |id|VU_ID|8| |All| |entityType| unsigned 16-bit integer | 2| | All| |x| Signed 16-bit integer | 2| | All| |y| Signed 16-bit integer | 2| | All| |z| single-precision 32-bit floating point | 4| | >=70 | |spotTime| unsigned 32-bit integer | 4| | All | |spotted| signed 16-bit integer | 2| | All | |baseFlags | signed 16-bit integer | 2| | All | |owner | byte | 1| | All | |campId | signed 16-bit integer | 2| | All | |last_check| unsigned 32-bit integer| 4| | All| |roster| Signed 32-bit integer| 4| | All| |unit_flags| Signed 32-bit integer| 4| | All| |dest_x| Signed 16-bit integer| 2| | All| |dest_y| Signed 16-bit integer| 2| | All| |target_id|VU_ID|8| |All| |cargo_id|VU_ID|8| |> 1| |moved| byte| 1| | All| |losses| byte| 1| | All| |tactic| byte| 1| | All| |current_wp| unsigned 16-bit integer| 2| | > = 71| |current_wp| byte| 1| | < 71| |name_id| Signed 16-bit integer| 2| | All| |reinforcement| Signed 16-bit integer| 2| | All| |numWaypoints| unsigned 16-bit integer| 2| | > = 71| |numWaypoints| byte | 1| | < 71| |waypoints[]| Waypoint[numWaypoints]| | | All| |elements| byte|1 | | All| |element[]| VU_ID[elements] | (elements * 8) bytes | | All| |interceptor| VU_ID | 8 | | All| |awacs| VU_ID | 8 | | > = 7| |jstar| VU_ID | 8 | | > = 7| |ecm| VU_ID | 8 | | > = 7| |tanker| VU_ID | 8 | | > = 7| |wait_cycles| byte | 1 | | All| |flights| byte | 1 | | All| |wait_for| Signed 16-bit integer| 2 | | All| |iax| Signed 16-bit integer| 2 | | All| |iay| Signed 16-bit integer| 2 | | All| |eax| Signed 16-bit integer| 2 | | All| |eay| Signed 16-bit integer| 2 | | All| |bpx| Signed 16-bit integer| 2 | | All| |bpy| Signed 16-bit integer| 2 | | All| |tpx| Signed 16-bit integer| 2 | | All| |tpy| Signed 16-bit integer| 2 | | All| |takeoff| unsigned 32-bit integer| 4 | | All| |tp_time| unsigned 32-bit integer| 4 | | All| |caps| Signed 16-bit integer| 2 | | All| |requests| Signed 16-bit integer| 2 | | All| |threat_stats| Signed 16-bit integer| 2 | | < 35| |responses| Signed 16-bit integer| 2 | | All| |num_ingress_waypoints| byte| 1 | | All| |ingress_waypoints[]| Waypoint[num_ingress_waypoints| | | All| |num_egress_waypoints| byte| 1 | | All| |egress_waypoints[]| Waypoint[num_egress_waypoints| | | All| |mis_request| MissionRequest| | | All| ==== Brigade structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |id|VU_ID|8| |All| |entityType| unsigned 16-bit integer | 2| | All| |x| Signed 16-bit integer | 2| | All| |y| Signed 16-bit integer | 2| | All| |z| single-precision 32-bit floating point | 4| | >=70 | |spotTime| unsigned 32-bit integer | 4| | All | |spotted| signed 16-bit integer | 2| | All | |baseFlags | signed 16-bit integer | 2| | All | |owner | byte | 1| | All | |campId | signed 16-bit integer | 2| | All | |last_check| unsigned 32-bit integer| 4| | All| |roster| Signed 32-bit integer| 4| | All| |unit_flags| Signed 32-bit integer| 4| | All| |dest_x| Signed 16-bit integer| 2| | All| |dest_y| Signed 16-bit integer| 2| | All| |target_id|VU_ID|8| |All| |cargo_id|VU_ID|8| |> 1| |moved| byte| 1| | All| |losses| byte| 1| | All| |tactic| byte| 1| | All| |current_wp| unsigned 16-bit integer| 2| | > = 71| |current_wp| byte| 1| | < 71| |name_id| Signed 16-bit integer| 2| | All| |reinforcement| Signed 16-bit integer| 2| | All| |numWaypoints| unsigned 16-bit integer| 2| | > = 71| |numWaypoints| byte | 1| | < 71| |waypoints[]| Waypoint[numWaypoints]| | | All| |orders| byte | 1 | | All| |division| Signed 16-bit integer | 2 | | All| |aobj| VU_ID| 8 | | All| |elements| byte| 1| | All| |element[]| VU_ID[elements]| (elements * 8) bytes| | All| ==== Battalion structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |id|VU_ID|8| |All| |entityType| unsigned 16-bit integer | 2| | All| |x| Signed 16-bit integer | 2| | All| |y| Signed 16-bit integer | 2| | All| |z| single-precision 32-bit floating point | 4| | >=70 | |spotTime| unsigned 32-bit integer | 4| | All | |spotted| signed 16-bit integer | 2| | All | |baseFlags | signed 16-bit integer | 2| | All | |owner | byte | 1| | All | |campId | signed 16-bit integer | 2| | All | |last_check| unsigned 32-bit integer| 4| | All| |roster| Signed 32-bit integer| 4| | All| |unit_flags| Signed 32-bit integer| 4| | All| |dest_x| Signed 16-bit integer| 2| | All| |dest_y| Signed 16-bit integer| 2| | All| |target_id|VU_ID|8| |All| |cargo_id|VU_ID|8| |> 1| |moved| byte| 1| | All| |losses| byte| 1| | All| |tactic| byte| 1| | All| |current_wp| unsigned 16-bit integer| 2| | > = 71| |current_wp| byte| 1| | < 71| |name_id| Signed 16-bit integer| 2| | All| |reinforcement| Signed 16-bit integer| 2| | All| |numWaypoints| unsigned 16-bit integer| 2| | > = 71| |numWaypoints| byte | 1| | < 71| |waypoints[]| Waypoint[numWaypoints]| | | All| |orders| byte | 1 | | All| |division| Signed 16-bit integer | 2 | | All| |aobj| VU_ID| 8 | | All| |last_move| unsigned 32-bit integer| 4 | | All| |last_combat| unsigned 32-bit integer| 4 | | All| |parent_id| VU_ID| 8 | | All| |last_obj| VU_ID| 8 | | All| |supply|byte| 1 | | All| |fatigue|byte| 1 | | All| |morale|byte| 1 | | All| |heading|byte| 1 | | All| |final_heading|byte| 1 | | All| |dummy|byte| 1 | | < 15| |position|byte| 1 | | All| ==== TaskForce structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |id|VU_ID|8| |All| |entityType| unsigned 16-bit integer | 2| | All| |x| Signed 16-bit integer | 2| | All| |y| Signed 16-bit integer | 2| | All| |z| single-precision 32-bit floating point | 4| | >=70 | |spotTime| unsigned 32-bit integer | 4| | All | |spotted| signed 16-bit integer | 2| | All | |baseFlags | signed 16-bit integer | 2| | All | |owner | byte | 1| | All | |campId | signed 16-bit integer | 2| | All | |last_check| unsigned 32-bit integer| 4| | All| |roster| Signed 32-bit integer| 4| | All| |unit_flags| Signed 32-bit integer| 4| | All| |dest_x| Signed 16-bit integer| 2| | All| |dest_y| Signed 16-bit integer| 2| | All| |target_id|VU_ID|8| |All| |cargo_id|VU_ID|8| |> 1| |moved| byte| 1| | All| |losses| byte| 1| | All| |tactic| byte| 1| | All| |current_wp| unsigned 16-bit integer| 2| | > = 71| |current_wp| byte| 1| | < 71| |name_id| Signed 16-bit integer| 2| | All| |reinforcement| Signed 16-bit integer| 2| | All| |numWaypoints| unsigned 16-bit integer| 2| | > = 71| |numWaypoints| byte | 1| | < 71| |waypoints[]| Waypoint[numWaypoints]| | | All| |orders| byte | 1| | All| |supply| byte | 1| | All| ==== MissionRequest structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |requesterID|VU_ID|8 | |All| |targetID|VU_ID|8 | |All| |secondaryID|VU_ID|8 | |All| |pakID|VU_ID|8 | |All| |who|byte|1 | |All| |vs|byte|1 | |All| |padding[]|byte[2]|2 |necessary so data lands on an Int32 boundary |All| |tot|unsigned 32-bit integer|4 | |All| |tx|Signed 16-bit integer|2 | |All| |ty|Signed 16-bit integer|2 | |All| |flags|unsigned 32-bit integer|4 | |All| |caps|Signed 16-bit integer|2 | |All| |target_num|Signed 16-bit integer|2 | |All| |speed|Signed 16-bit integer|2 | |All| |match_strength|Signed 16-bit integer|2 | |All| |priority|Signed 16-bit integer|2 | |All| |tot_type|byte|1 | |All| |action_type|byte|1 | |All| |mission|byte|1 | |All| |aircraft|byte|1 | |All| |context|byte|1 | |All| |roe_check|byte|1 | |All| |delayed|byte|1 | |> = 35| |start_block|byte|1 | |> = 35| |final_block|byte|1 | |> = 35| |slots[]|byte[4]|4 | |> = 35| |min_to|byte|1 | |> = 35| |max_to|byte|1 | |> = 35| |morepadding[]|byte[3]|3 | necessary so data lands on an Int32 boundary|> = 35| ==== Pilot structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |pilot_id|Signed 16-bit integer|2 | |All| |pilot_skill_and_rating|byte|1 |low nibble=skill; hi nibble = rating |All| |pilot_status|byte|1 | |All| |aa_kills|byte|1 | |All| |ag_kills|byte|1 | |All| |as_kills|byte|1 | |All| |an_kills|byte|1 | |All| |missions_flown|Signed 16-bit integer|2 | |> = 48| ==== LoadoutArray structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |Stores[]|LoadoutStruct[5]| 5 * 32 = 160 bytes| |All| ==== LoadoutStruct structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |WeaponID[]|byte[16]|16| |All| |WeaponCount[]|byte[16]|16| |All| ==== Waypoint structure ==== ^Field^Data Type^Width (in bytes)^Description^Versions^ |haves|byte|1| |All| |GridX|Signed 16-bit integer|2| |All| |GridY|Signed 16-bit integer|2| |All| |GridZ|Signed 16-bit integer|2| |All| |Arrive|unsigned 32-bit integer|4| |All| |Action|byte|1| |All| |RouteAction|byte|1| |All| |Formation|byte|1| |All| |Flags|Signed 16-bit integer|2| |All| |TargetID|VU_ID|8|only present if "haves" <> 0 |All| |TargetBuilding|byte|1|only present if "haves" <> 0, else set value=255 |All| |Depart|unsigned 32-bit integer|4|only present if "haves" <> 0, else set to same val as "Arrive" |All| ==== VU_ID structure ==== ^Field^Data Type^Width (in bytes)^Description^ |num_|unsigned 32-bit integer|4| | |creator_|unsigned 32-bit integer|4| |