Ground named cargo production event descriptors
This commit is contained in:
parent
358d4cdec3
commit
6a5d028d19
14 changed files with 987 additions and 217 deletions
|
|
@ -48,8 +48,9 @@ bounded runtime landing surface too: representative descriptors import into
|
|||
`world.hotel_revenue`. The grounded aggregate cargo-economics descriptors now have bounded
|
||||
runtime landing surfaces too: descriptor `105` `All Cargo Prices` plus descriptors `177..179`
|
||||
`All Cargo Production` / `All Factory Production` / `All Farm/Mine Production` import into
|
||||
event-owned cargo override state, while the named cargo-price and named cargo-production strips
|
||||
remain explicit `blocked_evidence_blocked_descriptor` parity until descriptor ordering is pinned
|
||||
event-owned cargo override state, and the grounded named cargo-production strip `180..229` now
|
||||
imports into named cargo production overrides too. The named cargo-price strip `106..176`
|
||||
remains explicit `blocked_evidence_blocked_descriptor` parity until descriptor ordering is pinned
|
||||
more strongly. The first grounded
|
||||
condition-side unlock now exists for negative-sentinel `raw_condition_id = -1` company scopes, and
|
||||
the first ordinary nonnegative condition batch now executes too: numeric-threshold company
|
||||
|
|
|
|||
360
artifacts/exports/rt3-1.06/event-effects-cargo-bindings.json
Normal file
360
artifacts/exports/rt3-1.06/event-effects-cargo-bindings.json
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
{
|
||||
"binding_catalog_version": 1,
|
||||
"notes": [
|
||||
"Named cargo production bindings are grounded from the checked-in 1.06 CargoTypes corpus and the candidate-loader evidence that live cargo names are materialized in lexicographic order.",
|
||||
"The named production strip has 50 rows, so the checked-in binding covers the 50-name lexicographic corpus used by the grounded 1.06 runtime baseline and leaves the named cargo price strip unresolved.",
|
||||
"Rock remains outside the grounded 50-row production strip in this batch."
|
||||
],
|
||||
"bindings": [
|
||||
{
|
||||
"descriptor_id": 180,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Alcohol",
|
||||
"binding_index": 1,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 181,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Aluminum",
|
||||
"binding_index": 2,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 182,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Ammunition",
|
||||
"binding_index": 3,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 183,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Automobiles",
|
||||
"binding_index": 4,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 184,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Bauxite",
|
||||
"binding_index": 5,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 185,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Ceramics",
|
||||
"binding_index": 6,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 186,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Cheese",
|
||||
"binding_index": 7,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 187,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Chemicals",
|
||||
"binding_index": 8,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 188,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Clothing",
|
||||
"binding_index": 9,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 189,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Coal",
|
||||
"binding_index": 10,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 190,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Coffee",
|
||||
"binding_index": 11,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 191,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Concrete",
|
||||
"binding_index": 12,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 192,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Corn",
|
||||
"binding_index": 13,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 193,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Cotton",
|
||||
"binding_index": 14,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 194,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Crystals",
|
||||
"binding_index": 15,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 195,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Diesel",
|
||||
"binding_index": 16,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 196,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Dye",
|
||||
"binding_index": 17,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 197,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Electronics",
|
||||
"binding_index": 18,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 198,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Fertilizer",
|
||||
"binding_index": 19,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 199,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Furniture",
|
||||
"binding_index": 20,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 200,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Goods",
|
||||
"binding_index": 21,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 201,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Grain",
|
||||
"binding_index": 22,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 202,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Ingots",
|
||||
"binding_index": 23,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 203,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Iron",
|
||||
"binding_index": 24,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 204,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Livestock",
|
||||
"binding_index": 25,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 205,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Logs",
|
||||
"binding_index": 26,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 206,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Lumber",
|
||||
"binding_index": 27,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 207,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Machinery",
|
||||
"binding_index": 28,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 208,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Mail",
|
||||
"binding_index": 29,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 209,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Meat",
|
||||
"binding_index": 30,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 210,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Medicine",
|
||||
"binding_index": 31,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 211,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Milk",
|
||||
"binding_index": 32,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 212,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Oil",
|
||||
"binding_index": 33,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 213,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Ore",
|
||||
"binding_index": 34,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 214,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Paper",
|
||||
"binding_index": 35,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 215,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Passengers",
|
||||
"binding_index": 36,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 216,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Plastic",
|
||||
"binding_index": 37,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 217,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Produce",
|
||||
"binding_index": 38,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 218,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Pulpwood",
|
||||
"binding_index": 39,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 219,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Rice",
|
||||
"binding_index": 40,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 220,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Rubber",
|
||||
"binding_index": 41,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 221,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Steel",
|
||||
"binding_index": 42,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 222,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Sugar",
|
||||
"binding_index": 43,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 223,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Tires",
|
||||
"binding_index": 44,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 224,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Toys",
|
||||
"binding_index": 45,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 225,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Troops",
|
||||
"binding_index": 46,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 226,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Uranium",
|
||||
"binding_index": 47,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 227,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Waste",
|
||||
"binding_index": 48,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 228,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Weapons",
|
||||
"binding_index": 49,
|
||||
"binding_source": "static"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 229,
|
||||
"band": "cargo_production_named",
|
||||
"cargo_name": "Wool",
|
||||
"binding_index": 50,
|
||||
"binding_source": "static"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1625,453 +1625,453 @@
|
|||
},
|
||||
{
|
||||
"descriptor_id": 180,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Alcohol Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 181,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Aluminum Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 182,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Ammunition Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 183,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Automobiles Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 184,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Bauxite Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 185,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Ceramics Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 186,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Cheese Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 187,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Chemicals Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 188,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Clothing Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 189,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Coal Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 190,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Coffee Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 191,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Concrete Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 192,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Corn Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 193,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Cotton Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 194,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Crystals Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 195,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Diesel Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 196,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Dye Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 197,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Electronics Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 198,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Fertilizer Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 199,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Furniture Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 200,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Goods Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 201,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Grain Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 202,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Ingots Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 203,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Iron Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 204,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Livestock Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 205,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Logs Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 206,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Lumber Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 207,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Machinery Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 208,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Mail Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 209,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Meat Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 210,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Medicine Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 211,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Milk Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 212,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Oil Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 213,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Ore Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 214,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Paper Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 215,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Passengers Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 216,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Plastic Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 217,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Produce Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 218,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Pulpwood Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 219,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Rice Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 220,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Rubber Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 221,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Steel Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 222,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Sugar Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 223,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Tires Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 224,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Toys Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 225,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Troops Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 226,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Uranium Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 227,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Waste Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 228,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Weapons Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 229,
|
||||
"label": "Unknown Cargo Production",
|
||||
"label": "Wool Production",
|
||||
"target_mask_bits": 15,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"runtime_key": null,
|
||||
"runtime_status": "evidence_blocked",
|
||||
"executable_in_runtime": false
|
||||
"runtime_status": "executable",
|
||||
"executable_in_runtime": true
|
||||
},
|
||||
{
|
||||
"descriptor_id": 230,
|
||||
|
|
|
|||
|
|
@ -119,10 +119,49 @@ pub fn write_indexed_collection_probe(
|
|||
Ok(path)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct CargoCollectionProbeRow {
|
||||
pub entry_id: usize,
|
||||
pub live: bool,
|
||||
pub resolved_ptr: usize,
|
||||
pub stem: Option<String>,
|
||||
pub route_style_byte: Option<u8>,
|
||||
pub subtype_byte: Option<u8>,
|
||||
pub class_marker: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct CargoCollectionProbe {
|
||||
pub collection_addr: usize,
|
||||
pub flat_payload: bool,
|
||||
pub stride: u32,
|
||||
pub id_bound: i32,
|
||||
pub payload_ptr: usize,
|
||||
pub tombstone_ptr: usize,
|
||||
pub live_entry_count: usize,
|
||||
pub rows: Vec<CargoCollectionProbeRow>,
|
||||
}
|
||||
|
||||
pub fn write_cargo_collection_probe(
|
||||
base_dir: &Path,
|
||||
stem: &str,
|
||||
probe: &CargoCollectionProbe,
|
||||
) -> io::Result<PathBuf> {
|
||||
fs::create_dir_all(base_dir)?;
|
||||
|
||||
let path = base_dir.join(format!("rrt_cargo_{stem}_collection_probe.json"));
|
||||
let json = serde_json::to_vec_pretty(probe)
|
||||
.map_err(|err| io::Error::other(format!("serialize cargo collection probe: {err}")))?;
|
||||
fs::write(&path, json)?;
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
mod windows_hook {
|
||||
use super::{
|
||||
IndexedCollectionProbe, IndexedCollectionProbeRow, sample_finance_snapshot,
|
||||
CargoCollectionProbe, CargoCollectionProbeRow, IndexedCollectionProbe,
|
||||
IndexedCollectionProbeRow, sample_finance_snapshot, write_cargo_collection_probe,
|
||||
write_finance_snapshot_bundle, write_finance_snapshot_only, write_indexed_collection_probe,
|
||||
};
|
||||
use core::ffi::{c_char, c_void};
|
||||
|
|
@ -160,6 +199,9 @@ mod windows_hook {
|
|||
static FINANCE_CAPTURE_PROBE_WRITTEN_MESSAGE: &[u8] =
|
||||
b"rrt-hook: finance probe snapshot written\n";
|
||||
static FINANCE_CAPTURE_TIMEOUT_MESSAGE: &[u8] = b"rrt-hook: finance capture timed out\n";
|
||||
static CARGO_CAPTURE_STARTED_MESSAGE: &[u8] = b"rrt-hook: cargo capture thread started\n";
|
||||
static CARGO_CAPTURE_WRITTEN_MESSAGE: &[u8] = b"rrt-hook: cargo collection probe written\n";
|
||||
static CARGO_CAPTURE_TIMEOUT_MESSAGE: &[u8] = b"rrt-hook: cargo capture timed out\n";
|
||||
static AUTO_LOAD_STARTED_MESSAGE: &[u8] = b"rrt-hook: auto load hook armed\n";
|
||||
static AUTO_LOAD_HOOK_INSTALLED_MESSAGE: &[u8] =
|
||||
b"rrt-hook: auto load shell-state hook installed\n";
|
||||
|
|
@ -284,6 +326,7 @@ mod windows_hook {
|
|||
static FINANCE_TEMPLATE_EMITTED: AtomicBool = AtomicBool::new(false);
|
||||
static FINANCE_CAPTURE_STARTED: AtomicBool = AtomicBool::new(false);
|
||||
static FINANCE_COLLECTION_PROBE_WRITTEN: AtomicBool = AtomicBool::new(false);
|
||||
static CARGO_CAPTURE_STARTED: AtomicBool = AtomicBool::new(false);
|
||||
static AUTO_LOAD_THREAD_STARTED: AtomicBool = AtomicBool::new(false);
|
||||
static AUTO_LOAD_HOOK_INSTALLED: AtomicBool = AtomicBool::new(false);
|
||||
static AUTO_LOAD_ATTEMPTED: AtomicBool = AtomicBool::new(false);
|
||||
|
|
@ -324,6 +367,7 @@ mod windows_hook {
|
|||
static mut MODE2_TEARDOWN_TRAMPOLINE: usize = 0;
|
||||
|
||||
const COMPANY_COLLECTION_ADDR: usize = 0x0062be10;
|
||||
const CARGO_COLLECTION_ADDR: usize = 0x0062ba8c;
|
||||
const SHELL_CONTROLLER_PTR_ADDR: usize = 0x006d4024;
|
||||
const SHELL_STATE_PTR_ADDR: usize = 0x006cec74;
|
||||
const ACTIVE_MODE_PTR_ADDR: usize = 0x006cec78;
|
||||
|
|
@ -360,6 +404,10 @@ mod windows_hook {
|
|||
const INDEXED_COLLECTION_ID_BOUND_OFFSET: usize = 0x14;
|
||||
const INDEXED_COLLECTION_PAYLOAD_OFFSET: usize = 0x30;
|
||||
const INDEXED_COLLECTION_TOMBSTONE_BITSET_OFFSET: usize = 0x34;
|
||||
const CARGO_STEM_OFFSET: usize = 0x04;
|
||||
const CARGO_SUBTYPE_OFFSET: usize = 0x32;
|
||||
const CARGO_ROUTE_STYLE_OFFSET: usize = 0x46;
|
||||
const CARGO_COLLECTION_CLASS_MARKER_BASE_OFFSET: usize = 0x9a;
|
||||
const COMPANY_ACTIVE_OFFSET: usize = 0x3f;
|
||||
const COMPANY_OUTSTANDING_SHARES_OFFSET: usize = 0x47;
|
||||
const COMPANY_COMPANY_VALUE_OFFSET: usize = 0x57;
|
||||
|
|
@ -493,6 +541,7 @@ mod windows_hook {
|
|||
) -> i32 {
|
||||
maybe_emit_finance_template_bundle();
|
||||
maybe_start_finance_capture_thread();
|
||||
maybe_start_cargo_capture_thread();
|
||||
maybe_install_auto_load_hook();
|
||||
|
||||
let direct_input8_create = unsafe { load_direct_input8_create() };
|
||||
|
|
@ -592,6 +641,41 @@ mod windows_hook {
|
|||
});
|
||||
}
|
||||
|
||||
fn maybe_start_cargo_capture_thread() {
|
||||
if env::var_os("RRT_WRITE_CARGO_CAPTURE").is_none() {
|
||||
return;
|
||||
}
|
||||
if CARGO_CAPTURE_STARTED.swap(true, Ordering::AcqRel) {
|
||||
return;
|
||||
}
|
||||
|
||||
append_log_message(CARGO_CAPTURE_STARTED_MESSAGE);
|
||||
let base_dir = env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
|
||||
let _ = thread::Builder::new()
|
||||
.name("rrt-cargo-capture".to_string())
|
||||
.spawn(move || {
|
||||
let mut last_probe: Option<CargoCollectionProbe> = None;
|
||||
for _ in 0..MAX_CAPTURE_POLL_ATTEMPTS {
|
||||
if let Some(probe) = unsafe { capture_cargo_collection_probe() } {
|
||||
last_probe = Some(probe.clone());
|
||||
if probe.live_entry_count > 0
|
||||
&& write_cargo_collection_probe(&base_dir, "attach_probe", &probe)
|
||||
.is_ok()
|
||||
{
|
||||
append_log_message(CARGO_CAPTURE_WRITTEN_MESSAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
thread::sleep(CAPTURE_POLL_INTERVAL);
|
||||
}
|
||||
|
||||
if let Some(probe) = last_probe {
|
||||
let _ = write_cargo_collection_probe(&base_dir, "attach_probe_timeout", &probe);
|
||||
}
|
||||
append_log_message(CARGO_CAPTURE_TIMEOUT_MESSAGE);
|
||||
});
|
||||
}
|
||||
|
||||
fn maybe_install_auto_load_hook() {
|
||||
let save_stem = match env::var("RRT_AUTO_LOAD_SAVE") {
|
||||
Ok(value) if !value.trim().is_empty() => value,
|
||||
|
|
@ -2751,6 +2835,93 @@ mod windows_hook {
|
|||
})
|
||||
}
|
||||
|
||||
unsafe fn capture_cargo_collection_probe() -> Option<CargoCollectionProbe> {
|
||||
let collection = CARGO_COLLECTION_ADDR as *const u8;
|
||||
let id_bound = unsafe { read_i32(collection.add(INDEXED_COLLECTION_ID_BOUND_OFFSET)) };
|
||||
if id_bound <= 0 {
|
||||
return Some(CargoCollectionProbe {
|
||||
collection_addr: CARGO_COLLECTION_ADDR,
|
||||
flat_payload: unsafe {
|
||||
read_u32(collection.add(INDEXED_COLLECTION_FLAT_FLAG_OFFSET)) != 0
|
||||
},
|
||||
stride: unsafe { read_u32(collection.add(INDEXED_COLLECTION_STRIDE_OFFSET)) },
|
||||
id_bound,
|
||||
payload_ptr: unsafe {
|
||||
read_ptr(collection.add(INDEXED_COLLECTION_PAYLOAD_OFFSET)) as usize
|
||||
},
|
||||
tombstone_ptr: unsafe {
|
||||
read_ptr(collection.add(INDEXED_COLLECTION_TOMBSTONE_BITSET_OFFSET)) as usize
|
||||
},
|
||||
live_entry_count: 0,
|
||||
rows: Vec::new(),
|
||||
});
|
||||
}
|
||||
|
||||
let mut live_entry_count = 0_usize;
|
||||
let mut rows = Vec::with_capacity(id_bound as usize);
|
||||
for entry_id in 1..=id_bound as usize {
|
||||
let live = unsafe { indexed_collection_entry_id_is_live(collection, entry_id) };
|
||||
let resolved_ptr = unsafe {
|
||||
indexed_collection_resolve_live_entry_by_id(collection, entry_id) as usize
|
||||
};
|
||||
if live && resolved_ptr != 0 {
|
||||
live_entry_count += 1;
|
||||
}
|
||||
let stem = if resolved_ptr == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe {
|
||||
read_c_string((resolved_ptr as *const u8).add(CARGO_STEM_OFFSET), 0x1e)
|
||||
})
|
||||
};
|
||||
let route_style_byte = if resolved_ptr == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { read_u8((resolved_ptr as *const u8).add(CARGO_ROUTE_STYLE_OFFSET)) })
|
||||
};
|
||||
let subtype_byte = if resolved_ptr == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { read_u8((resolved_ptr as *const u8).add(CARGO_SUBTYPE_OFFSET)) })
|
||||
};
|
||||
let class_marker = if live {
|
||||
Some(unsafe {
|
||||
read_u32(
|
||||
collection.add(CARGO_COLLECTION_CLASS_MARKER_BASE_OFFSET + entry_id * 4),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
rows.push(CargoCollectionProbeRow {
|
||||
entry_id,
|
||||
live,
|
||||
resolved_ptr,
|
||||
stem,
|
||||
route_style_byte,
|
||||
subtype_byte,
|
||||
class_marker,
|
||||
});
|
||||
}
|
||||
|
||||
Some(CargoCollectionProbe {
|
||||
collection_addr: CARGO_COLLECTION_ADDR,
|
||||
flat_payload: unsafe {
|
||||
read_u32(collection.add(INDEXED_COLLECTION_FLAT_FLAG_OFFSET)) != 0
|
||||
},
|
||||
stride: unsafe { read_u32(collection.add(INDEXED_COLLECTION_STRIDE_OFFSET)) },
|
||||
id_bound,
|
||||
payload_ptr: unsafe {
|
||||
read_ptr(collection.add(INDEXED_COLLECTION_PAYLOAD_OFFSET)) as usize
|
||||
},
|
||||
tombstone_ptr: unsafe {
|
||||
read_ptr(collection.add(INDEXED_COLLECTION_TOMBSTONE_BITSET_OFFSET)) as usize
|
||||
},
|
||||
live_entry_count,
|
||||
rows,
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn capture_probe_snapshot_from_company(company: *mut u8) -> FinanceSnapshot {
|
||||
let scenario = unsafe { read_ptr(ACTIVE_MODE_PTR_ADDR as *const u8) } as *const u8;
|
||||
let current_year = unsafe { read_u16(scenario.add(SCENARIO_CURRENT_YEAR_OFFSET)) };
|
||||
|
|
@ -2905,6 +3076,18 @@ mod windows_hook {
|
|||
unsafe { ptr::read_unaligned(address.cast::<*mut u8>()) }
|
||||
}
|
||||
|
||||
unsafe fn read_c_string(address: *const u8, max_len: usize) -> String {
|
||||
let mut len = 0;
|
||||
while len < max_len {
|
||||
let byte = unsafe { read_u8(address.add(len)) };
|
||||
if byte == 0 {
|
||||
break;
|
||||
}
|
||||
len += 1;
|
||||
}
|
||||
String::from_utf8_lossy(unsafe { std::slice::from_raw_parts(address, len) }).into_owned()
|
||||
}
|
||||
|
||||
unsafe fn load_direct_input8_create() -> Option<DirectInput8CreateFn> {
|
||||
if let Some(callback) = unsafe { REAL_DINPUT8_CREATE } {
|
||||
return Some(callback);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ pub const REQUIRED_EXPORTS: &[&str] = &[
|
|||
"artifacts/exports/rt3-1.06/pending-template-store-record-kinds.csv",
|
||||
"artifacts/exports/rt3-1.06/pending-template-store-management.md",
|
||||
"artifacts/exports/rt3-1.06/event-effects-table.json",
|
||||
"artifacts/exports/rt3-1.06/event-effects-cargo-bindings.json",
|
||||
"artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json",
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ enum ImportBlocker {
|
|||
NamedTerritoryBinding,
|
||||
UnmappedOrdinaryCondition,
|
||||
UnmappedWorldCondition,
|
||||
EvidenceBlockedDescriptor,
|
||||
MissingTrainContext,
|
||||
MissingTrainTerritoryContext,
|
||||
MissingLocomotiveCatalogContext,
|
||||
|
|
@ -1216,6 +1217,7 @@ fn runtime_packed_event_grouped_effect_row_summary_from_smp(
|
|||
.or_else(|| row.recovered_cargo_class.clone()),
|
||||
recovered_cargo_label: cargo_entry
|
||||
.map(|entry| entry.label.clone())
|
||||
.or_else(|| row.recovered_cargo_label.clone())
|
||||
.or_else(|| row.recovered_cargo_slot.map(default_cargo_slot_label)),
|
||||
recovered_cargo_supplied_token_stem: cargo_entry
|
||||
.and_then(|entry| entry.supplied_token_stem.clone()),
|
||||
|
|
@ -1488,6 +1490,15 @@ fn lower_contextual_cargo_production_effect(
|
|||
target: RuntimeCargoProductionTarget::FarmMine,
|
||||
value,
|
||||
})),
|
||||
180..=229 => {
|
||||
let Some(name) = row.recovered_cargo_label.clone() else {
|
||||
return Err(ImportBlocker::EvidenceBlockedDescriptor);
|
||||
};
|
||||
Ok(Some(RuntimeEffect::SetCargoProductionOverride {
|
||||
target: RuntimeCargoProductionTarget::Named { name },
|
||||
value,
|
||||
}))
|
||||
}
|
||||
230..=240 => {
|
||||
let Some(slot) = row.descriptor_id.checked_sub(229) else {
|
||||
return Ok(None);
|
||||
|
|
@ -2650,6 +2661,9 @@ fn company_target_import_error_message(
|
|||
Some(ImportBlocker::NamedTerritoryBinding) => {
|
||||
"packed condition requires named territory binding".to_string()
|
||||
}
|
||||
Some(ImportBlocker::EvidenceBlockedDescriptor) => {
|
||||
"packed descriptor is still evidence-blocked".to_string()
|
||||
}
|
||||
Some(ImportBlocker::UnmappedOrdinaryCondition) => {
|
||||
"packed ordinary condition is not yet mapped".to_string()
|
||||
}
|
||||
|
|
@ -3107,6 +3121,7 @@ fn company_target_import_outcome(blocker: ImportBlocker) -> &'static str {
|
|||
ImportBlocker::NamedTerritoryBinding => "blocked_named_territory_binding",
|
||||
ImportBlocker::UnmappedOrdinaryCondition => "blocked_unmapped_ordinary_condition",
|
||||
ImportBlocker::UnmappedWorldCondition => "blocked_unmapped_world_condition",
|
||||
ImportBlocker::EvidenceBlockedDescriptor => "blocked_evidence_blocked_descriptor",
|
||||
ImportBlocker::MissingTrainContext => "blocked_missing_train_context",
|
||||
ImportBlocker::MissingTrainTerritoryContext => "blocked_missing_train_territory_context",
|
||||
ImportBlocker::MissingLocomotiveCatalogContext => {
|
||||
|
|
@ -3832,6 +3847,7 @@ mod tests {
|
|||
semantic_preview: Some("Set Company Cash to 7 with aux [2, 3, 24, 36]".to_string()),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: Some("Mikado".to_string()),
|
||||
notes: vec!["grouped effect row carries locomotive-name side string".to_string()],
|
||||
|
|
@ -3866,6 +3882,7 @@ mod tests {
|
|||
)),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -3895,6 +3912,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set Company Track Pieces Buildable to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -3924,6 +3942,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set Credit Rating to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -3955,6 +3974,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set Merger Premium to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![
|
||||
|
|
@ -3992,6 +4012,7 @@ mod tests {
|
|||
)),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4027,6 +4048,7 @@ mod tests {
|
|||
)),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes,
|
||||
|
|
@ -4056,6 +4078,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set Economic Status to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4087,6 +4110,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set Limited Track Building Amount to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4118,6 +4142,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set Use Wartime Cargos to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4149,6 +4174,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set Turbo Diesel Availability to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4264,6 +4290,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set {descriptor_label} to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4374,6 +4401,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set {descriptor_label} to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4628,6 +4656,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set {descriptor_label} to {value}")),
|
||||
recovered_cargo_slot: Some(slot),
|
||||
recovered_cargo_class,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4657,6 +4686,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set All Cargo Prices to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![
|
||||
|
|
@ -4691,6 +4721,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set Unknown Cargo Price to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![
|
||||
|
|
@ -4731,6 +4762,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set {label} to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![
|
||||
|
|
@ -4743,11 +4775,19 @@ mod tests {
|
|||
descriptor_id: u32,
|
||||
value: i32,
|
||||
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||
let cargo_label = match descriptor_id {
|
||||
180 => Some("Alcohol".to_string()),
|
||||
_ => None,
|
||||
};
|
||||
let descriptor_label = cargo_label
|
||||
.as_ref()
|
||||
.map(|label| format!("{label} Production"))
|
||||
.unwrap_or_else(|| "Unknown Cargo Production".to_string());
|
||||
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||
group_index: 0,
|
||||
row_index: 0,
|
||||
descriptor_id,
|
||||
descriptor_label: Some("Unknown Cargo Production".to_string()),
|
||||
descriptor_label: Some(descriptor_label.clone()),
|
||||
target_mask_bits: Some(0x08),
|
||||
parameter_family: Some("cargo_production_scalar".to_string()),
|
||||
grouped_target_subject: None,
|
||||
|
|
@ -4762,9 +4802,10 @@ mod tests {
|
|||
value_word_0x16: 0,
|
||||
row_shape: "scalar_assignment".to_string(),
|
||||
semantic_family: Some("scalar_assignment".to_string()),
|
||||
semantic_preview: Some(format!("Set Unknown Cargo Production to {value}")),
|
||||
semantic_preview: Some(format!("Set {descriptor_label} to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: cargo_label,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![
|
||||
|
|
@ -4798,6 +4839,7 @@ mod tests {
|
|||
semantic_preview: Some(format!("Set Territory Access Cost to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4834,6 +4876,7 @@ mod tests {
|
|||
)),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4868,6 +4911,7 @@ mod tests {
|
|||
)),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -4904,6 +4948,7 @@ mod tests {
|
|||
)),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: locomotive_name.map(ToString::to_string),
|
||||
notes,
|
||||
|
|
@ -4933,6 +4978,7 @@ mod tests {
|
|||
semantic_preview: Some("Set Confiscate All to FALSE".to_string()),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -6952,6 +6998,7 @@ mod tests {
|
|||
),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: Some(10),
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
|
|
@ -8066,7 +8113,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn keeps_named_cargo_production_rows_evidence_blocked() {
|
||||
fn imports_named_cargo_production_rows_when_binding_is_grounded() {
|
||||
let save_slice = SmpLoadedSaveSlice {
|
||||
file_extension_hint: Some("gms".to_string()),
|
||||
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
|
||||
|
|
@ -8096,13 +8143,13 @@ mod tests {
|
|||
live_record_count: 1,
|
||||
live_entry_ids: vec![40],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 0,
|
||||
imported_runtime_record_count: 1,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 40,
|
||||
payload_offset: Some(0x7202),
|
||||
payload_len: Some(96),
|
||||
decode_status: "parity_only".to_string(),
|
||||
decode_status: "executable".to_string(),
|
||||
payload_family: "real_packed_v1".to_string(),
|
||||
trigger_kind: Some(7),
|
||||
active: None,
|
||||
|
|
@ -8116,30 +8163,45 @@ mod tests {
|
|||
grouped_effect_row_counts: vec![1, 0, 0, 0],
|
||||
grouped_effect_rows: vec![real_named_cargo_production_row(180, 160)],
|
||||
decoded_conditions: Vec::new(),
|
||||
decoded_actions: vec![],
|
||||
executable_import_ready: false,
|
||||
notes: vec!["named cargo production descriptors remain evidence-blocked until cargo ordering is pinned"
|
||||
decoded_actions: vec![RuntimeEffect::SetCargoProductionOverride {
|
||||
target: RuntimeCargoProductionTarget::Named {
|
||||
name: "Alcohol".to_string(),
|
||||
},
|
||||
value: 160,
|
||||
}],
|
||||
executable_import_ready: true,
|
||||
notes: vec!["named cargo production descriptors now import through named cargo overrides"
|
||||
.to_string()],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let import = project_save_slice_to_runtime_state_import(
|
||||
let mut import = project_save_slice_to_runtime_state_import(
|
||||
&save_slice,
|
||||
"packed-events-named-cargo-production-parity",
|
||||
None,
|
||||
)
|
||||
.expect("save slice should project");
|
||||
|
||||
assert!(import.state.event_runtime_records.is_empty());
|
||||
assert_eq!(import.state.event_runtime_records.len(), 1);
|
||||
execute_step_command(
|
||||
&mut import.state,
|
||||
&StepCommand::ServiceTriggerKind { trigger_kind: 7 },
|
||||
)
|
||||
.expect("named cargo production runtime record should run");
|
||||
|
||||
assert_eq!(
|
||||
import.state.named_cargo_production_overrides.get("Alcohol"),
|
||||
Some(&160)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.packed_event_collection
|
||||
.as_ref()
|
||||
.and_then(|summary| summary.records[0].import_outcome.as_deref()),
|
||||
Some("blocked_evidence_blocked_descriptor")
|
||||
Some("imported")
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -8451,6 +8513,7 @@ mod tests {
|
|||
),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: Some("Mikado".to_string()),
|
||||
notes: vec![
|
||||
|
|
@ -10080,6 +10143,7 @@ mod tests {
|
|||
semantic_preview: Some("Set Turbo Diesel Availability to 1".to_string()),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_cargo_label: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec!["checked-in whole-game grouped-effect sample".to_string()],
|
||||
|
|
|
|||
|
|
@ -2189,6 +2189,8 @@ pub struct SmpLoadedPackedEventGroupedEffectRowSummary {
|
|||
#[serde(default)]
|
||||
pub recovered_cargo_class: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_label: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_locomotive_id: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub locomotive_name: Option<String>,
|
||||
|
|
@ -3510,6 +3512,11 @@ fn parse_real_grouped_effect_row_summary(
|
|||
"cargo-production descriptor maps to world production slot {cargo_slot}"
|
||||
));
|
||||
}
|
||||
if let Some(cargo_label) = grounded_named_cargo_production_label(descriptor_id) {
|
||||
notes.push(format!(
|
||||
"named cargo production descriptor maps to cargo {cargo_label}"
|
||||
));
|
||||
}
|
||||
|
||||
Some(SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||
group_index,
|
||||
|
|
@ -3543,6 +3550,8 @@ fn parse_real_grouped_effect_row_summary(
|
|||
recovered_cargo_class: recovered_cargo_production_slot(descriptor_id)
|
||||
.and_then(known_cargo_slot_definition)
|
||||
.map(|definition| runtime_cargo_class_name(definition.cargo_class).to_string()),
|
||||
recovered_cargo_label: grounded_named_cargo_production_label(descriptor_id)
|
||||
.map(ToString::to_string),
|
||||
recovered_locomotive_id: recovered_locomotive_availability_loco_id(descriptor_id)
|
||||
.or_else(|| recovered_locomotive_cost_loco_id(descriptor_id)),
|
||||
locomotive_name,
|
||||
|
|
@ -3789,9 +3798,87 @@ fn recovered_cargo_economics_descriptor_metadata(
|
|||
}
|
||||
}
|
||||
|
||||
const GROUNDED_NAMED_CARGO_PRODUCTION_LABELS: [(&str, &str); 50] = [
|
||||
("Alcohol", "Alcohol Production"),
|
||||
("Aluminum", "Aluminum Production"),
|
||||
("Ammunition", "Ammunition Production"),
|
||||
("Automobiles", "Automobiles Production"),
|
||||
("Bauxite", "Bauxite Production"),
|
||||
("Ceramics", "Ceramics Production"),
|
||||
("Cheese", "Cheese Production"),
|
||||
("Chemicals", "Chemicals Production"),
|
||||
("Clothing", "Clothing Production"),
|
||||
("Coal", "Coal Production"),
|
||||
("Coffee", "Coffee Production"),
|
||||
("Concrete", "Concrete Production"),
|
||||
("Corn", "Corn Production"),
|
||||
("Cotton", "Cotton Production"),
|
||||
("Crystals", "Crystals Production"),
|
||||
("Diesel", "Diesel Production"),
|
||||
("Dye", "Dye Production"),
|
||||
("Electronics", "Electronics Production"),
|
||||
("Fertilizer", "Fertilizer Production"),
|
||||
("Furniture", "Furniture Production"),
|
||||
("Goods", "Goods Production"),
|
||||
("Grain", "Grain Production"),
|
||||
("Ingots", "Ingots Production"),
|
||||
("Iron", "Iron Production"),
|
||||
("Livestock", "Livestock Production"),
|
||||
("Logs", "Logs Production"),
|
||||
("Lumber", "Lumber Production"),
|
||||
("Machinery", "Machinery Production"),
|
||||
("Mail", "Mail Production"),
|
||||
("Meat", "Meat Production"),
|
||||
("Medicine", "Medicine Production"),
|
||||
("Milk", "Milk Production"),
|
||||
("Oil", "Oil Production"),
|
||||
("Ore", "Ore Production"),
|
||||
("Paper", "Paper Production"),
|
||||
("Passengers", "Passengers Production"),
|
||||
("Plastic", "Plastic Production"),
|
||||
("Produce", "Produce Production"),
|
||||
("Pulpwood", "Pulpwood Production"),
|
||||
("Rice", "Rice Production"),
|
||||
("Rubber", "Rubber Production"),
|
||||
("Steel", "Steel Production"),
|
||||
("Sugar", "Sugar Production"),
|
||||
("Tires", "Tires Production"),
|
||||
("Toys", "Toys Production"),
|
||||
("Troops", "Troops Production"),
|
||||
("Uranium", "Uranium Production"),
|
||||
("Waste", "Waste Production"),
|
||||
("Weapons", "Weapons Production"),
|
||||
("Wool", "Wool Production"),
|
||||
];
|
||||
|
||||
fn grounded_named_cargo_production_label(descriptor_id: u32) -> Option<&'static str> {
|
||||
let index = descriptor_id.checked_sub(180)? as usize;
|
||||
GROUNDED_NAMED_CARGO_PRODUCTION_LABELS
|
||||
.get(index)
|
||||
.map(|(cargo_label, _)| *cargo_label)
|
||||
}
|
||||
|
||||
fn grounded_named_cargo_production_descriptor_label(descriptor_id: u32) -> Option<&'static str> {
|
||||
let index = descriptor_id.checked_sub(180)? as usize;
|
||||
GROUNDED_NAMED_CARGO_PRODUCTION_LABELS
|
||||
.get(index)
|
||||
.map(|(_, descriptor_label)| *descriptor_label)
|
||||
}
|
||||
|
||||
fn recovered_cargo_production_descriptor_metadata(
|
||||
descriptor_id: u32,
|
||||
) -> Option<RealGroupedEffectDescriptorMetadata> {
|
||||
if let Some(label) = grounded_named_cargo_production_descriptor_label(descriptor_id) {
|
||||
return Some(RealGroupedEffectDescriptorMetadata {
|
||||
descriptor_id,
|
||||
label,
|
||||
target_mask_bits: 0x08,
|
||||
parameter_family: "cargo_production_scalar",
|
||||
runtime_key: None,
|
||||
runtime_status: RealGroupedEffectRuntimeStatus::Executable,
|
||||
executable_in_runtime: true,
|
||||
});
|
||||
}
|
||||
recovered_cargo_production_label(descriptor_id).map(|label| {
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
descriptor_id,
|
||||
|
|
@ -11493,6 +11580,18 @@ mod tests {
|
|||
assert!(metadata.executable_in_runtime);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn looks_up_grounded_named_cargo_production_descriptor_metadata() {
|
||||
let metadata =
|
||||
real_grouped_effect_descriptor_metadata(180).expect("descriptor metadata should exist");
|
||||
|
||||
assert_eq!(metadata.label, "Alcohol Production");
|
||||
assert_eq!(metadata.target_mask_bits, 0x08);
|
||||
assert_eq!(metadata.parameter_family, "cargo_production_scalar");
|
||||
assert_eq!(metadata.runtime_key, None);
|
||||
assert!(metadata.executable_in_runtime);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn looks_up_recovered_lower_band_locomotive_cost_descriptor_metadata() {
|
||||
let metadata =
|
||||
|
|
@ -11556,6 +11655,33 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_grounded_named_cargo_production_row_with_label() {
|
||||
let row_bytes = build_real_grouped_effect_row(RealGroupedEffectRowSpec {
|
||||
descriptor_id: 180,
|
||||
raw_scalar_value: 160,
|
||||
opcode: 3,
|
||||
value_byte_0x09: 0,
|
||||
value_dword_0x0d: 0,
|
||||
value_byte_0x11: 0,
|
||||
value_byte_0x12: 0,
|
||||
value_word_0x14: 0,
|
||||
value_word_0x16: 0,
|
||||
locomotive_name: None,
|
||||
});
|
||||
|
||||
let row = parse_real_grouped_effect_row_summary(&row_bytes, 0, 0, None)
|
||||
.expect("row should parse");
|
||||
|
||||
assert_eq!(row.descriptor_id, 180);
|
||||
assert_eq!(row.descriptor_label.as_deref(), Some("Alcohol Production"));
|
||||
assert_eq!(row.recovered_cargo_label.as_deref(), Some("Alcohol"));
|
||||
assert_eq!(
|
||||
row.parameter_family.as_deref(),
|
||||
Some("cargo_production_scalar")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn looks_up_recovered_locomotive_policy_descriptor_metadata() {
|
||||
let metadata =
|
||||
|
|
|
|||
|
|
@ -115,8 +115,9 @@ The highest-value next passes are now:
|
|||
`world.track_maintenance_cost`
|
||||
- the grounded aggregate cargo-economics descriptors now execute too: descriptor `105`
|
||||
`All Cargo Prices` and descriptors `177..179` `All Cargo Production` / `All Factory Production`
|
||||
/ `All Farm/Mine Production` land on bounded event-owned cargo override state, while the named
|
||||
cargo-price and named cargo-production strips remain explicit
|
||||
/ `All Farm/Mine Production` land on bounded event-owned cargo override state, and the grounded
|
||||
named cargo-production strip `180..229` now lands on named cargo production overrides too
|
||||
- the named cargo-price strip `106..176` remains explicit
|
||||
`blocked_evidence_blocked_descriptor` parity until descriptor ordering is pinned more strongly
|
||||
- widen real packed-event executable coverage descriptor by descriptor after identity, target mask,
|
||||
and normalized effect semantics are all grounded, not just after row framing is parsed
|
||||
|
|
|
|||
|
|
@ -77,8 +77,9 @@ Implemented today:
|
|||
`RuntimeState.world_scalar_overrides`
|
||||
- the grounded aggregate cargo-economics descriptors now execute too: descriptor `105`
|
||||
`All Cargo Prices` and descriptors `177..179` `All Cargo Production` / `All Factory Production`
|
||||
/ `All Farm/Mine Production` import through bounded cargo override surfaces, while the named
|
||||
cargo-price and named cargo-production strips now sit on explicit
|
||||
/ `All Farm/Mine Production` import through bounded cargo override surfaces, and the grounded
|
||||
named cargo-production strip `180..229` now imports through named cargo production overrides too
|
||||
- the named cargo-price strip `106..176` now sits on explicit
|
||||
`blocked_evidence_blocked_descriptor` parity instead of generic unmapped-descriptor frontier
|
||||
- a minimal event-owned train surface and an opaque economic-status lane now exist in runtime
|
||||
state, and real descriptors `8` = `Economic Status`, `9` = `Confiscate All`, and `15` =
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"fixture_id": "packed-event-cargo-economics-parity-save-slice-fixture",
|
||||
"source": {
|
||||
"kind": "captured-runtime",
|
||||
"description": "Fixture pinning the remaining named cargo-economics descriptor strips on explicit evidence-blocked parity."
|
||||
"description": "Fixture pinning the remaining named cargo-price descriptor strip on explicit evidence-blocked parity."
|
||||
},
|
||||
"state_save_slice_path": "packed-event-cargo-economics-parity-save-slice.json",
|
||||
"commands": [
|
||||
|
|
@ -34,12 +34,6 @@
|
|||
"descriptor_label": "Unknown Cargo Price",
|
||||
"parameter_family": "cargo_price_scalar",
|
||||
"semantic_family": "scalar_assignment"
|
||||
},
|
||||
{
|
||||
"descriptor_id": 180,
|
||||
"descriptor_label": "Unknown Cargo Production",
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"semantic_family": "scalar_assignment"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
"format_version": 1,
|
||||
"save_slice_id": "packed-event-cargo-economics-parity-save-slice",
|
||||
"source": {
|
||||
"description": "Tracked save-slice document pinning the remaining named cargo-economics descriptor strips on explicit evidence-blocked parity.",
|
||||
"description": "Tracked save-slice document pinning the remaining named cargo-price descriptor strip on explicit evidence-blocked parity.",
|
||||
"original_save_filename": "captured-cargo-economics-parity.gms",
|
||||
"original_save_sha256": "cargo-economics-parity-sample-sha256",
|
||||
"notes": [
|
||||
"tracked as JSON save-slice document rather than raw .smp",
|
||||
"pins named cargo price and named cargo production rows until exact descriptor-to-cargo ordering is grounded strongly enough"
|
||||
"pins the named cargo-price strip until exact descriptor-to-cargo ordering is grounded strongly enough"
|
||||
]
|
||||
},
|
||||
"save_slice": {
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
"record_index": 0,
|
||||
"live_entry_id": 65,
|
||||
"payload_offset": 33696,
|
||||
"payload_len": 128,
|
||||
"payload_len": 96,
|
||||
"decode_status": "parity_only",
|
||||
"payload_family": "real_packed_v1",
|
||||
"trigger_kind": 7,
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
"text_bands": [],
|
||||
"standalone_condition_row_count": 0,
|
||||
"standalone_condition_rows": [],
|
||||
"grouped_effect_row_counts": [2, 0, 0, 0],
|
||||
"grouped_effect_row_counts": [1, 0, 0, 0],
|
||||
"grouped_effect_rows": [
|
||||
{
|
||||
"group_index": 0,
|
||||
|
|
@ -93,45 +93,18 @@
|
|||
"descriptor recovered from checked-in EventEffects semantic catalog",
|
||||
"exact named cargo ordering for the price strip is not yet pinned"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_index": 0,
|
||||
"row_index": 1,
|
||||
"descriptor_id": 180,
|
||||
"descriptor_label": "Unknown Cargo Production",
|
||||
"target_mask_bits": 8,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"opcode": 3,
|
||||
"raw_scalar_value": 160,
|
||||
"value_byte_0x09": 0,
|
||||
"value_dword_0x0d": 0,
|
||||
"value_byte_0x11": 0,
|
||||
"value_byte_0x12": 0,
|
||||
"value_word_0x14": 0,
|
||||
"value_word_0x16": 0,
|
||||
"row_shape": "scalar_assignment",
|
||||
"semantic_family": "scalar_assignment",
|
||||
"semantic_preview": "Set Unknown Cargo Production to 160",
|
||||
"recovered_cargo_slot": null,
|
||||
"recovered_cargo_class": null,
|
||||
"recovered_locomotive_id": null,
|
||||
"locomotive_name": null,
|
||||
"notes": [
|
||||
"descriptor recovered from checked-in EventEffects semantic catalog",
|
||||
"exact named cargo ordering for the production strip is not yet pinned"
|
||||
]
|
||||
}
|
||||
],
|
||||
"decoded_actions": [],
|
||||
"executable_import_ready": false,
|
||||
"notes": [
|
||||
"named cargo-economics descriptor strips remain explicit evidence-blocked parity"
|
||||
"named cargo-price descriptors remain explicit evidence-blocked parity"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"notes": [
|
||||
"named cargo economics evidence-blocked parity sample"
|
||||
"named cargo price evidence-blocked parity sample"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"fixture_id": "packed-event-cargo-economics-save-slice-fixture",
|
||||
"source": {
|
||||
"kind": "captured-runtime",
|
||||
"description": "Fixture proving the grounded aggregate cargo-economics descriptors execute through bounded cargo override surfaces."
|
||||
"description": "Fixture proving the grounded aggregate cargo-economics descriptors plus the grounded named production strip execute through bounded cargo override surfaces."
|
||||
},
|
||||
"state_save_slice_path": "packed-event-cargo-economics-save-slice.json",
|
||||
"commands": [
|
||||
|
|
@ -28,6 +28,9 @@
|
|||
"all_cargo_production_override": 210,
|
||||
"factory_cargo_production_override": 225,
|
||||
"farm_mine_cargo_production_override": 175,
|
||||
"named_cargo_production_overrides": {
|
||||
"Alcohol": 160
|
||||
},
|
||||
"packed_event_collection": {
|
||||
"records": [
|
||||
{
|
||||
|
|
@ -67,6 +70,14 @@
|
|||
"kind": "farm_mine"
|
||||
},
|
||||
"value": 175
|
||||
},
|
||||
{
|
||||
"kind": "set_cargo_production_override",
|
||||
"target": {
|
||||
"kind": "named",
|
||||
"name": "Alcohol"
|
||||
},
|
||||
"value": 160
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
"format_version": 1,
|
||||
"save_slice_id": "packed-event-cargo-economics-save-slice",
|
||||
"source": {
|
||||
"description": "Tracked save-slice document proving the grounded aggregate cargo-economics descriptors execute through bounded cargo override surfaces.",
|
||||
"description": "Tracked save-slice document proving the grounded aggregate and named-production cargo-economics descriptors execute through bounded cargo override surfaces.",
|
||||
"original_save_filename": "captured-cargo-economics.gms",
|
||||
"original_save_sha256": "cargo-economics-sample-sha256",
|
||||
"notes": [
|
||||
"tracked as JSON save-slice document rather than raw .smp",
|
||||
"pins the grounded aggregate descriptors 105 and 177..179 while named cargo strips remain evidence-blocked"
|
||||
"pins the grounded aggregate descriptors 105 and 177..179 plus the grounded named production strip 180..229 while named cargo price remains evidence-blocked"
|
||||
]
|
||||
},
|
||||
"save_slice": {
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
"record_index": 0,
|
||||
"live_entry_id": 64,
|
||||
"payload_offset": 32800,
|
||||
"payload_len": 176,
|
||||
"payload_len": 208,
|
||||
"decode_status": "executable",
|
||||
"payload_family": "real_packed_v1",
|
||||
"trigger_kind": 7,
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
"text_bands": [],
|
||||
"standalone_condition_row_count": 0,
|
||||
"standalone_condition_rows": [],
|
||||
"grouped_effect_row_counts": [4, 0, 0, 0],
|
||||
"grouped_effect_row_counts": [5, 0, 0, 0],
|
||||
"grouped_effect_rows": [
|
||||
{
|
||||
"group_index": 0,
|
||||
|
|
@ -170,6 +170,34 @@
|
|||
"notes": [
|
||||
"descriptor recovered from checked-in EventEffects semantic catalog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_index": 0,
|
||||
"row_index": 4,
|
||||
"descriptor_id": 180,
|
||||
"descriptor_label": "Alcohol Production",
|
||||
"target_mask_bits": 8,
|
||||
"parameter_family": "cargo_production_scalar",
|
||||
"opcode": 3,
|
||||
"raw_scalar_value": 160,
|
||||
"value_byte_0x09": 0,
|
||||
"value_dword_0x0d": 0,
|
||||
"value_byte_0x11": 0,
|
||||
"value_byte_0x12": 0,
|
||||
"value_word_0x14": 0,
|
||||
"value_word_0x16": 0,
|
||||
"row_shape": "scalar_assignment",
|
||||
"semantic_family": "scalar_assignment",
|
||||
"semantic_preview": "Set Alcohol Production to 160",
|
||||
"recovered_cargo_slot": null,
|
||||
"recovered_cargo_class": null,
|
||||
"recovered_cargo_label": "Alcohol",
|
||||
"recovered_locomotive_id": null,
|
||||
"locomotive_name": null,
|
||||
"notes": [
|
||||
"descriptor recovered from checked-in EventEffects semantic catalog",
|
||||
"named cargo production descriptor maps to cargo Alcohol"
|
||||
]
|
||||
}
|
||||
],
|
||||
"decoded_actions": [
|
||||
|
|
@ -200,17 +228,25 @@
|
|||
"kind": "farm_mine"
|
||||
},
|
||||
"value": 175
|
||||
},
|
||||
{
|
||||
"kind": "set_cargo_production_override",
|
||||
"target": {
|
||||
"kind": "named",
|
||||
"name": "Alcohol"
|
||||
},
|
||||
"value": 160
|
||||
}
|
||||
],
|
||||
"executable_import_ready": true,
|
||||
"notes": [
|
||||
"grounded aggregate cargo economics descriptors execute through bounded cargo override surfaces"
|
||||
"grounded aggregate cargo economics descriptors plus the grounded named production strip execute through bounded cargo override surfaces"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"notes": [
|
||||
"aggregate cargo economics executable sample"
|
||||
"aggregate cargo economics plus named production executable sample"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,20 @@ def locomotive_cost_label(locomotive_id: int) -> str:
|
|||
return f"Lower-Band Locomotive Cost Slot {locomotive_id}"
|
||||
|
||||
|
||||
def classify(row: dict[str, object]) -> dict[str, object]:
|
||||
def load_cargo_bindings(raw_table_path: Path) -> dict[int, dict[str, object]]:
|
||||
bindings_path = raw_table_path.parent / "event-effects-cargo-bindings.json"
|
||||
if not bindings_path.exists():
|
||||
return {}
|
||||
artifact = json.loads(bindings_path.read_text(encoding="utf-8"))
|
||||
return {
|
||||
int(binding["descriptor_id"]): binding
|
||||
for binding in artifact.get("bindings", [])
|
||||
}
|
||||
|
||||
|
||||
def classify(
|
||||
row: dict[str, object], cargo_bindings: dict[int, dict[str, object]]
|
||||
) -> dict[str, object]:
|
||||
descriptor_id = int(row["descriptor_id"])
|
||||
label = str(row["label"])
|
||||
signature_byte_0x63 = int(row["signature_byte_0x63"])
|
||||
|
|
@ -142,6 +155,11 @@ def classify(row: dict[str, object]) -> dict[str, object]:
|
|||
executable_in_runtime = True
|
||||
elif 180 <= descriptor_id <= 229:
|
||||
parameter_family = "cargo_production_scalar"
|
||||
binding = cargo_bindings.get(descriptor_id)
|
||||
if binding is not None:
|
||||
label = f"{binding['cargo_name']} Production"
|
||||
runtime_status = "executable"
|
||||
executable_in_runtime = True
|
||||
elif 230 <= descriptor_id <= 240:
|
||||
parameter_family = "cargo_production_scalar"
|
||||
runtime_status = "executable"
|
||||
|
|
@ -213,7 +231,8 @@ def main() -> None:
|
|||
args = parser.parse_args()
|
||||
|
||||
raw_artifact = json.loads(args.raw_table.read_text(encoding="utf-8"))
|
||||
descriptors = [classify(row) for row in raw_artifact["descriptors"]]
|
||||
cargo_bindings = load_cargo_bindings(args.raw_table)
|
||||
descriptors = [classify(row, cargo_bindings) for row in raw_artifact["descriptors"]]
|
||||
artifact = {
|
||||
"descriptor_count": len(descriptors),
|
||||
"raw_table_binary_sha256": raw_artifact.get("binary_sha256"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue