Probe raw save selection context
This commit is contained in:
parent
bd9e1421a1
commit
40c0e94ad5
9 changed files with 581 additions and 137 deletions
|
|
@ -29,7 +29,10 @@ chairman ordinals remain explicit frontier. Checked-in save-slice
|
||||||
documents can now also carry explicit company rosters and chairman-profile tables, so the current
|
documents can now also carry explicit company rosters and chairman-profile tables, so the current
|
||||||
company-targeted and chairman-targeted descriptor and condition batches can execute from standalone
|
company-targeted and chairman-targeted descriptor and condition batches can execute from standalone
|
||||||
save-slice fixtures without overlay snapshots when that context is present; raw `.gms` inspection
|
save-slice fixtures without overlay snapshots when that context is present; raw `.gms` inspection
|
||||||
still does not reconstruct those company/chairman collections automatically. A checked-in
|
still does not reconstruct those company/chairman collections automatically, but it now does
|
||||||
|
reconstruct selection-only company/chairman context from the fixed save-side `0x32c8` world block.
|
||||||
|
Those raw selected ids can flow through save-slice export/import and override overlay-backed base
|
||||||
|
selection even while the full raw rosters remain absent. A checked-in
|
||||||
`EventEffects` export now exists too in
|
`EventEffects` export now exists too in
|
||||||
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer now
|
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer now
|
||||||
exists beside it in `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`. Recovered
|
exists beside it in `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`. Recovered
|
||||||
|
|
@ -55,7 +58,9 @@ runtime landing surfaces too: descriptor `105` `All Cargo Prices` plus descripto
|
||||||
event-owned cargo override state, and the grounded named cargo-production strip `180..229` now
|
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`
|
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
|
remains explicit `blocked_evidence_blocked_descriptor` parity until descriptor ordering is pinned
|
||||||
more strongly. The add-building strip `503..519` is now explicitly classified as recovered
|
more strongly, but the semantic catalog now gives that band stable `Named Cargo Price Slot N`
|
||||||
|
labels instead of anonymous `Unknown Cargo Price` residue. The add-building strip `503..519` is
|
||||||
|
now explicitly classified as recovered
|
||||||
shell-owned descriptor parity rather than generic unresolved residue. The first grounded
|
shell-owned descriptor parity rather than generic unresolved residue. The first grounded
|
||||||
condition-side unlock now exists for negative-sentinel `raw_condition_id = -1` company scopes, and
|
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
|
the first ordinary nonnegative condition batch now executes too: numeric-threshold company
|
||||||
|
|
|
||||||
|
|
@ -959,7 +959,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 106,
|
"descriptor_id": 106,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 1",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -968,7 +968,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 107,
|
"descriptor_id": 107,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 2",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -977,7 +977,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 108,
|
"descriptor_id": 108,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 3",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -986,7 +986,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 109,
|
"descriptor_id": 109,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 4",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -995,7 +995,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 110,
|
"descriptor_id": 110,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 5",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1004,7 +1004,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 111,
|
"descriptor_id": 111,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 6",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1013,7 +1013,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 112,
|
"descriptor_id": 112,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 7",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1022,7 +1022,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 113,
|
"descriptor_id": 113,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 8",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1031,7 +1031,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 114,
|
"descriptor_id": 114,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 9",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1040,7 +1040,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 115,
|
"descriptor_id": 115,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 10",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1049,7 +1049,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 116,
|
"descriptor_id": 116,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 11",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1058,7 +1058,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 117,
|
"descriptor_id": 117,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 12",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1067,7 +1067,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 118,
|
"descriptor_id": 118,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 13",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1076,7 +1076,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 119,
|
"descriptor_id": 119,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 14",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1085,7 +1085,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 120,
|
"descriptor_id": 120,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 15",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1094,7 +1094,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 121,
|
"descriptor_id": 121,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 16",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1103,7 +1103,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 122,
|
"descriptor_id": 122,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 17",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1112,7 +1112,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 123,
|
"descriptor_id": 123,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 18",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1121,7 +1121,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 124,
|
"descriptor_id": 124,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 19",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1130,7 +1130,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 125,
|
"descriptor_id": 125,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 20",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1139,7 +1139,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 126,
|
"descriptor_id": 126,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 21",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1148,7 +1148,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 127,
|
"descriptor_id": 127,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 22",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1157,7 +1157,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 128,
|
"descriptor_id": 128,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 23",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1166,7 +1166,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 129,
|
"descriptor_id": 129,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 24",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1175,7 +1175,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 130,
|
"descriptor_id": 130,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 25",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1184,7 +1184,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 131,
|
"descriptor_id": 131,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 26",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1193,7 +1193,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 132,
|
"descriptor_id": 132,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 27",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1202,7 +1202,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 133,
|
"descriptor_id": 133,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 28",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1211,7 +1211,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 134,
|
"descriptor_id": 134,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 29",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1220,7 +1220,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 135,
|
"descriptor_id": 135,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 30",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1229,7 +1229,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 136,
|
"descriptor_id": 136,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 31",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1238,7 +1238,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 137,
|
"descriptor_id": 137,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 32",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1247,7 +1247,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 138,
|
"descriptor_id": 138,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 33",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1256,7 +1256,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 139,
|
"descriptor_id": 139,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 34",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1265,7 +1265,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 140,
|
"descriptor_id": 140,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 35",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1274,7 +1274,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 141,
|
"descriptor_id": 141,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 36",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1283,7 +1283,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 142,
|
"descriptor_id": 142,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 37",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1292,7 +1292,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 143,
|
"descriptor_id": 143,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 38",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1301,7 +1301,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 144,
|
"descriptor_id": 144,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 39",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1310,7 +1310,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 145,
|
"descriptor_id": 145,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 40",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1319,7 +1319,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 146,
|
"descriptor_id": 146,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 41",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1328,7 +1328,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 147,
|
"descriptor_id": 147,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 42",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1337,7 +1337,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 148,
|
"descriptor_id": 148,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 43",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1346,7 +1346,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 149,
|
"descriptor_id": 149,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 44",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1355,7 +1355,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 150,
|
"descriptor_id": 150,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 45",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1364,7 +1364,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 151,
|
"descriptor_id": 151,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 46",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1373,7 +1373,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 152,
|
"descriptor_id": 152,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 47",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1382,7 +1382,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 153,
|
"descriptor_id": 153,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 48",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1391,7 +1391,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 154,
|
"descriptor_id": 154,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 49",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1400,7 +1400,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 155,
|
"descriptor_id": 155,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 50",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1409,7 +1409,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 156,
|
"descriptor_id": 156,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 51",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1418,7 +1418,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 157,
|
"descriptor_id": 157,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 52",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1427,7 +1427,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 158,
|
"descriptor_id": 158,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 53",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1436,7 +1436,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 159,
|
"descriptor_id": 159,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 54",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1445,7 +1445,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 160,
|
"descriptor_id": 160,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 55",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1454,7 +1454,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 161,
|
"descriptor_id": 161,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 56",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1463,7 +1463,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 162,
|
"descriptor_id": 162,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 57",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1472,7 +1472,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 163,
|
"descriptor_id": 163,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 58",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1481,7 +1481,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 164,
|
"descriptor_id": 164,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 59",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1490,7 +1490,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 165,
|
"descriptor_id": 165,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 60",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1499,7 +1499,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 166,
|
"descriptor_id": 166,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 61",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1508,7 +1508,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 167,
|
"descriptor_id": 167,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 62",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1517,7 +1517,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 168,
|
"descriptor_id": 168,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 63",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1526,7 +1526,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 169,
|
"descriptor_id": 169,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 64",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1535,7 +1535,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 170,
|
"descriptor_id": 170,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 65",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1544,7 +1544,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 171,
|
"descriptor_id": 171,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 66",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1553,7 +1553,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 172,
|
"descriptor_id": 172,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 67",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1562,7 +1562,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 173,
|
"descriptor_id": 173,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 68",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1571,7 +1571,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 174,
|
"descriptor_id": 174,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 69",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1580,7 +1580,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 175,
|
"descriptor_id": 175,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 70",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
@ -1589,7 +1589,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"descriptor_id": 176,
|
"descriptor_id": 176,
|
||||||
"label": "Unknown Cargo Price",
|
"label": "Named Cargo Price Slot 71",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"runtime_key": null,
|
"runtime_key": null,
|
||||||
|
|
|
||||||
|
|
@ -97,9 +97,11 @@ struct SaveSliceProjection {
|
||||||
event_runtime_records: Vec<RuntimeEventRecord>,
|
event_runtime_records: Vec<RuntimeEventRecord>,
|
||||||
companies: Vec<RuntimeCompany>,
|
companies: Vec<RuntimeCompany>,
|
||||||
has_company_projection: bool,
|
has_company_projection: bool,
|
||||||
|
has_company_selection_override: bool,
|
||||||
selected_company_id: Option<u32>,
|
selected_company_id: Option<u32>,
|
||||||
chairman_profiles: Vec<RuntimeChairmanProfile>,
|
chairman_profiles: Vec<RuntimeChairmanProfile>,
|
||||||
has_chairman_projection: bool,
|
has_chairman_projection: bool,
|
||||||
|
has_chairman_selection_override: bool,
|
||||||
selected_chairman_profile_id: Option<u32>,
|
selected_chairman_profile_id: Option<u32>,
|
||||||
candidate_availability: BTreeMap<String, u32>,
|
candidate_availability: BTreeMap<String, u32>,
|
||||||
named_locomotive_availability: BTreeMap<String, u32>,
|
named_locomotive_availability: BTreeMap<String, u32>,
|
||||||
|
|
@ -269,11 +271,19 @@ pub fn project_save_slice_to_runtime_state_import(
|
||||||
world_restore: projection.world_restore,
|
world_restore: projection.world_restore,
|
||||||
metadata: projection.metadata,
|
metadata: projection.metadata,
|
||||||
companies: projection.companies,
|
companies: projection.companies,
|
||||||
selected_company_id: projection.selected_company_id,
|
selected_company_id: if projection.has_company_projection {
|
||||||
|
projection.selected_company_id
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
players: Vec::new(),
|
players: Vec::new(),
|
||||||
selected_player_id: None,
|
selected_player_id: None,
|
||||||
chairman_profiles: projection.chairman_profiles,
|
chairman_profiles: projection.chairman_profiles,
|
||||||
selected_chairman_profile_id: projection.selected_chairman_profile_id,
|
selected_chairman_profile_id: if projection.has_chairman_projection {
|
||||||
|
projection.selected_chairman_profile_id
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
trains: Vec::new(),
|
trains: Vec::new(),
|
||||||
locomotive_catalog: projection.locomotive_catalog.unwrap_or_default(),
|
locomotive_catalog: projection.locomotive_catalog.unwrap_or_default(),
|
||||||
cargo_catalog: projection.cargo_catalog.unwrap_or_default(),
|
cargo_catalog: projection.cargo_catalog.unwrap_or_default(),
|
||||||
|
|
@ -349,7 +359,9 @@ pub fn project_save_slice_overlay_to_runtime_state_import(
|
||||||
} else {
|
} else {
|
||||||
base_state.companies.clone()
|
base_state.companies.clone()
|
||||||
},
|
},
|
||||||
selected_company_id: if projection.has_company_projection {
|
selected_company_id: if projection.has_company_projection
|
||||||
|
|| projection.has_company_selection_override
|
||||||
|
{
|
||||||
projection.selected_company_id
|
projection.selected_company_id
|
||||||
} else {
|
} else {
|
||||||
base_state.selected_company_id
|
base_state.selected_company_id
|
||||||
|
|
@ -361,7 +373,9 @@ pub fn project_save_slice_overlay_to_runtime_state_import(
|
||||||
} else {
|
} else {
|
||||||
base_state.chairman_profiles.clone()
|
base_state.chairman_profiles.clone()
|
||||||
},
|
},
|
||||||
selected_chairman_profile_id: if projection.has_chairman_projection {
|
selected_chairman_profile_id: if projection.has_chairman_projection
|
||||||
|
|| projection.has_chairman_selection_override
|
||||||
|
{
|
||||||
projection.selected_chairman_profile_id
|
projection.selected_chairman_profile_id
|
||||||
} else {
|
} else {
|
||||||
base_state.selected_chairman_profile_id
|
base_state.selected_chairman_profile_id
|
||||||
|
|
@ -809,7 +823,7 @@ fn project_save_slice_components(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let (companies, has_company_projection, selected_company_id) =
|
let (companies, has_company_projection, has_company_selection_override, selected_company_id) =
|
||||||
if let Some(roster) = &save_slice.company_roster {
|
if let Some(roster) = &save_slice.company_roster {
|
||||||
metadata.insert(
|
metadata.insert(
|
||||||
"save_slice.company_roster_source_kind".to_string(),
|
"save_slice.company_roster_source_kind".to_string(),
|
||||||
|
|
@ -829,55 +843,77 @@ fn project_save_slice_components(
|
||||||
selected_company_id.to_string(),
|
selected_company_id.to_string(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
(
|
if roster.entries.is_empty() {
|
||||||
roster
|
(
|
||||||
.entries
|
Vec::new(),
|
||||||
.iter()
|
false,
|
||||||
.map(|entry| RuntimeCompany {
|
roster.selected_company_id.is_some(),
|
||||||
company_id: entry.company_id,
|
roster.selected_company_id,
|
||||||
current_cash: entry.current_cash,
|
)
|
||||||
debt: entry.debt,
|
} else {
|
||||||
credit_rating_score: entry.credit_rating_score,
|
(
|
||||||
prime_rate: entry.prime_rate,
|
roster
|
||||||
active: entry.active,
|
.entries
|
||||||
available_track_laying_capacity: entry.available_track_laying_capacity,
|
.iter()
|
||||||
controller_kind: entry.controller_kind,
|
.map(|entry| RuntimeCompany {
|
||||||
linked_chairman_profile_id: entry.linked_chairman_profile_id,
|
company_id: entry.company_id,
|
||||||
book_value_per_share: entry.book_value_per_share,
|
current_cash: entry.current_cash,
|
||||||
investor_confidence: entry.investor_confidence,
|
debt: entry.debt,
|
||||||
management_attitude: entry.management_attitude,
|
credit_rating_score: entry.credit_rating_score,
|
||||||
takeover_cooldown_year: entry.takeover_cooldown_year,
|
prime_rate: entry.prime_rate,
|
||||||
merger_cooldown_year: entry.merger_cooldown_year,
|
active: entry.active,
|
||||||
track_piece_counts: entry.track_piece_counts,
|
available_track_laying_capacity: entry.available_track_laying_capacity,
|
||||||
})
|
controller_kind: entry.controller_kind,
|
||||||
.collect::<Vec<_>>(),
|
linked_chairman_profile_id: entry.linked_chairman_profile_id,
|
||||||
true,
|
book_value_per_share: entry.book_value_per_share,
|
||||||
roster.selected_company_id,
|
investor_confidence: entry.investor_confidence,
|
||||||
)
|
management_attitude: entry.management_attitude,
|
||||||
|
takeover_cooldown_year: entry.takeover_cooldown_year,
|
||||||
|
merger_cooldown_year: entry.merger_cooldown_year,
|
||||||
|
track_piece_counts: entry.track_piece_counts,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
true,
|
||||||
|
roster.selected_company_id.is_some(),
|
||||||
|
roster.selected_company_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
(Vec::new(), false, None)
|
(Vec::new(), false, false, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (chairman_profiles, has_chairman_projection, selected_chairman_profile_id) =
|
let (
|
||||||
if let Some(table) = &save_slice.chairman_profile_table {
|
chairman_profiles,
|
||||||
|
has_chairman_projection,
|
||||||
|
has_chairman_selection_override,
|
||||||
|
selected_chairman_profile_id,
|
||||||
|
) = if let Some(table) = &save_slice.chairman_profile_table {
|
||||||
|
metadata.insert(
|
||||||
|
"save_slice.chairman_profile_table_source_kind".to_string(),
|
||||||
|
table.source_kind.clone(),
|
||||||
|
);
|
||||||
|
metadata.insert(
|
||||||
|
"save_slice.chairman_profile_table_semantic_family".to_string(),
|
||||||
|
table.semantic_family.clone(),
|
||||||
|
);
|
||||||
|
metadata.insert(
|
||||||
|
"save_slice.chairman_profile_table_entry_count".to_string(),
|
||||||
|
table.observed_entry_count.to_string(),
|
||||||
|
);
|
||||||
|
if let Some(selected_chairman_profile_id) = table.selected_chairman_profile_id {
|
||||||
metadata.insert(
|
metadata.insert(
|
||||||
"save_slice.chairman_profile_table_source_kind".to_string(),
|
"save_slice.selected_chairman_profile_id".to_string(),
|
||||||
table.source_kind.clone(),
|
selected_chairman_profile_id.to_string(),
|
||||||
);
|
);
|
||||||
metadata.insert(
|
}
|
||||||
"save_slice.chairman_profile_table_semantic_family".to_string(),
|
if table.entries.is_empty() {
|
||||||
table.semantic_family.clone(),
|
(
|
||||||
);
|
Vec::new(),
|
||||||
metadata.insert(
|
false,
|
||||||
"save_slice.chairman_profile_table_entry_count".to_string(),
|
table.selected_chairman_profile_id.is_some(),
|
||||||
table.observed_entry_count.to_string(),
|
table.selected_chairman_profile_id,
|
||||||
);
|
)
|
||||||
if let Some(selected_chairman_profile_id) = table.selected_chairman_profile_id {
|
} else {
|
||||||
metadata.insert(
|
|
||||||
"save_slice.selected_chairman_profile_id".to_string(),
|
|
||||||
selected_chairman_profile_id.to_string(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
(
|
(
|
||||||
table
|
table
|
||||||
.entries
|
.entries
|
||||||
|
|
@ -895,11 +931,13 @@ fn project_save_slice_components(
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
true,
|
true,
|
||||||
|
table.selected_chairman_profile_id.is_some(),
|
||||||
table.selected_chairman_profile_id,
|
table.selected_chairman_profile_id,
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
(Vec::new(), false, None)
|
} else {
|
||||||
};
|
(Vec::new(), false, false, None)
|
||||||
|
};
|
||||||
|
|
||||||
let named_locomotive_cost = BTreeMap::new();
|
let named_locomotive_cost = BTreeMap::new();
|
||||||
let all_cargo_price_override = None;
|
let all_cargo_price_override = None;
|
||||||
|
|
@ -920,6 +958,8 @@ fn project_save_slice_components(
|
||||||
&& companies
|
&& companies
|
||||||
.iter()
|
.iter()
|
||||||
.all(|company| company.controller_kind != RuntimeCompanyControllerKind::Unknown);
|
.all(|company| company.controller_kind != RuntimeCompanyControllerKind::Unknown);
|
||||||
|
} else if has_company_selection_override {
|
||||||
|
packed_event_context.selected_company_id = selected_company_id;
|
||||||
}
|
}
|
||||||
if has_chairman_projection {
|
if has_chairman_projection {
|
||||||
packed_event_context.known_chairman_profile_ids = chairman_profiles
|
packed_event_context.known_chairman_profile_ids = chairman_profiles
|
||||||
|
|
@ -927,6 +967,8 @@ fn project_save_slice_components(
|
||||||
.map(|profile| profile.profile_id)
|
.map(|profile| profile.profile_id)
|
||||||
.collect();
|
.collect();
|
||||||
packed_event_context.selected_chairman_profile_id = selected_chairman_profile_id;
|
packed_event_context.selected_chairman_profile_id = selected_chairman_profile_id;
|
||||||
|
} else if has_chairman_selection_override {
|
||||||
|
packed_event_context.selected_chairman_profile_id = selected_chairman_profile_id;
|
||||||
}
|
}
|
||||||
if let Some(catalog) = &locomotive_catalog {
|
if let Some(catalog) = &locomotive_catalog {
|
||||||
packed_event_context.locomotive_catalog_names_by_id = catalog
|
packed_event_context.locomotive_catalog_names_by_id = catalog
|
||||||
|
|
@ -976,9 +1018,11 @@ fn project_save_slice_components(
|
||||||
event_runtime_records,
|
event_runtime_records,
|
||||||
companies,
|
companies,
|
||||||
has_company_projection,
|
has_company_projection,
|
||||||
|
has_company_selection_override,
|
||||||
selected_company_id,
|
selected_company_id,
|
||||||
chairman_profiles,
|
chairman_profiles,
|
||||||
has_chairman_projection,
|
has_chairman_projection,
|
||||||
|
has_chairman_selection_override,
|
||||||
selected_chairman_profile_id,
|
selected_chairman_profile_id,
|
||||||
candidate_availability,
|
candidate_availability,
|
||||||
named_locomotive_availability,
|
named_locomotive_availability,
|
||||||
|
|
@ -4918,11 +4962,12 @@ mod tests {
|
||||||
descriptor_id: u32,
|
descriptor_id: u32,
|
||||||
value: i32,
|
value: i32,
|
||||||
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||||
|
let slot = descriptor_id.saturating_sub(105);
|
||||||
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||||
group_index: 0,
|
group_index: 0,
|
||||||
row_index: 0,
|
row_index: 0,
|
||||||
descriptor_id,
|
descriptor_id,
|
||||||
descriptor_label: Some("Unknown Cargo Price".to_string()),
|
descriptor_label: Some(format!("Named Cargo Price Slot {slot}")),
|
||||||
target_mask_bits: Some(0x08),
|
target_mask_bits: Some(0x08),
|
||||||
parameter_family: Some("cargo_price_scalar".to_string()),
|
parameter_family: Some("cargo_price_scalar".to_string()),
|
||||||
grouped_target_subject: None,
|
grouped_target_subject: None,
|
||||||
|
|
@ -4937,7 +4982,7 @@ mod tests {
|
||||||
value_word_0x16: 0,
|
value_word_0x16: 0,
|
||||||
row_shape: "scalar_assignment".to_string(),
|
row_shape: "scalar_assignment".to_string(),
|
||||||
semantic_family: Some("scalar_assignment".to_string()),
|
semantic_family: Some("scalar_assignment".to_string()),
|
||||||
semantic_preview: Some(format!("Set Unknown Cargo Price to {value}")),
|
semantic_preview: Some(format!("Set Named Cargo Price Slot {slot} to {value}")),
|
||||||
recovered_cargo_slot: None,
|
recovered_cargo_slot: None,
|
||||||
recovered_cargo_class: None,
|
recovered_cargo_class: None,
|
||||||
recovered_cargo_label: None,
|
recovered_cargo_label: None,
|
||||||
|
|
@ -5874,6 +5919,118 @@ mod tests {
|
||||||
assert_eq!(import.state.territories, base_state.territories);
|
assert_eq!(import.state.territories, base_state.territories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn overlay_applies_selection_only_company_and_chairman_context_from_save_slice() {
|
||||||
|
let base_state = RuntimeState {
|
||||||
|
companies: vec![
|
||||||
|
crate::RuntimeCompany {
|
||||||
|
company_id: 1,
|
||||||
|
current_cash: 100,
|
||||||
|
debt: 0,
|
||||||
|
credit_rating_score: None,
|
||||||
|
prime_rate: None,
|
||||||
|
active: true,
|
||||||
|
available_track_laying_capacity: None,
|
||||||
|
controller_kind: RuntimeCompanyControllerKind::Human,
|
||||||
|
linked_chairman_profile_id: Some(1),
|
||||||
|
book_value_per_share: 0,
|
||||||
|
investor_confidence: 0,
|
||||||
|
management_attitude: 0,
|
||||||
|
takeover_cooldown_year: None,
|
||||||
|
merger_cooldown_year: None,
|
||||||
|
track_piece_counts: RuntimeTrackPieceCounts::default(),
|
||||||
|
},
|
||||||
|
crate::RuntimeCompany {
|
||||||
|
company_id: 42,
|
||||||
|
current_cash: 200,
|
||||||
|
debt: 0,
|
||||||
|
credit_rating_score: None,
|
||||||
|
prime_rate: None,
|
||||||
|
active: true,
|
||||||
|
available_track_laying_capacity: None,
|
||||||
|
controller_kind: RuntimeCompanyControllerKind::Human,
|
||||||
|
linked_chairman_profile_id: Some(9),
|
||||||
|
book_value_per_share: 0,
|
||||||
|
investor_confidence: 0,
|
||||||
|
management_attitude: 0,
|
||||||
|
takeover_cooldown_year: None,
|
||||||
|
merger_cooldown_year: None,
|
||||||
|
track_piece_counts: RuntimeTrackPieceCounts::default(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
selected_company_id: Some(42),
|
||||||
|
chairman_profiles: vec![
|
||||||
|
crate::RuntimeChairmanProfile {
|
||||||
|
profile_id: 1,
|
||||||
|
name: "Selected".to_string(),
|
||||||
|
active: true,
|
||||||
|
current_cash: 0,
|
||||||
|
linked_company_id: Some(1),
|
||||||
|
company_holdings: BTreeMap::new(),
|
||||||
|
holdings_value_total: 0,
|
||||||
|
net_worth_total: 0,
|
||||||
|
purchasing_power_total: 0,
|
||||||
|
},
|
||||||
|
crate::RuntimeChairmanProfile {
|
||||||
|
profile_id: 9,
|
||||||
|
name: "Base".to_string(),
|
||||||
|
active: true,
|
||||||
|
current_cash: 0,
|
||||||
|
linked_company_id: Some(42),
|
||||||
|
company_holdings: BTreeMap::new(),
|
||||||
|
holdings_value_total: 0,
|
||||||
|
net_worth_total: 0,
|
||||||
|
purchasing_power_total: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
selected_chairman_profile_id: Some(9),
|
||||||
|
..state()
|
||||||
|
};
|
||||||
|
let save_slice = SmpLoadedSaveSlice {
|
||||||
|
file_extension_hint: Some("gms".to_string()),
|
||||||
|
container_profile_family: Some("rt3-105-save-container-v1".to_string()),
|
||||||
|
mechanism_family: "rt3-105-save-post-span-bridge-v1".to_string(),
|
||||||
|
mechanism_confidence: "mixed".to_string(),
|
||||||
|
trailer_family: Some("rt3-105-save-trailer-v1".to_string()),
|
||||||
|
bridge_family: Some("rt3-105-save-post-span-bridge-v1".to_string()),
|
||||||
|
profile: None,
|
||||||
|
candidate_availability_table: None,
|
||||||
|
named_locomotive_availability_table: None,
|
||||||
|
locomotive_catalog: None,
|
||||||
|
cargo_catalog: None,
|
||||||
|
company_roster: Some(crate::SmpLoadedCompanyRoster {
|
||||||
|
source_kind: "save-direct-world-block-company-selection-only".to_string(),
|
||||||
|
semantic_family: "scenario-selected-company-context".to_string(),
|
||||||
|
observed_entry_count: 0,
|
||||||
|
selected_company_id: Some(1),
|
||||||
|
entries: Vec::new(),
|
||||||
|
}),
|
||||||
|
chairman_profile_table: Some(crate::SmpLoadedChairmanProfileTable {
|
||||||
|
source_kind: "save-direct-world-block-chairman-selection-only".to_string(),
|
||||||
|
semantic_family: "scenario-selected-chairman-context".to_string(),
|
||||||
|
observed_entry_count: 0,
|
||||||
|
selected_chairman_profile_id: Some(1),
|
||||||
|
entries: Vec::new(),
|
||||||
|
}),
|
||||||
|
special_conditions_table: None,
|
||||||
|
event_runtime_collection: None,
|
||||||
|
notes: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
let import = project_save_slice_overlay_to_runtime_state_import(
|
||||||
|
&base_state,
|
||||||
|
&save_slice,
|
||||||
|
"overlay-save-selection-only-context",
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.expect("overlay import should project");
|
||||||
|
|
||||||
|
assert_eq!(import.state.companies, base_state.companies);
|
||||||
|
assert_eq!(import.state.selected_company_id, Some(1));
|
||||||
|
assert_eq!(import.state.chairman_profiles, base_state.chairman_profiles);
|
||||||
|
assert_eq!(import.state.selected_chairman_profile_id, Some(1));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn projects_executable_packed_records_into_runtime_and_services_follow_on() {
|
fn projects_executable_packed_records_into_runtime_and_services_follow_on() {
|
||||||
let save_slice = SmpLoadedSaveSlice {
|
let save_slice = SmpLoadedSaveSlice {
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,11 @@ const RECIPE_BOOK_LINE_STRIDE: usize = 0x30;
|
||||||
const RECIPE_BOOK_LINE_AREA_LEN: usize = RECIPE_BOOK_LINE_COUNT * RECIPE_BOOK_LINE_STRIDE;
|
const RECIPE_BOOK_LINE_AREA_LEN: usize = RECIPE_BOOK_LINE_COUNT * RECIPE_BOOK_LINE_STRIDE;
|
||||||
const RECIPE_BOOK_SUMMARY_END_OFFSET: usize =
|
const RECIPE_BOOK_SUMMARY_END_OFFSET: usize =
|
||||||
RECIPE_BOOK_ROOT_OFFSET + RECIPE_BOOK_COUNT * RECIPE_BOOK_STRIDE;
|
RECIPE_BOOK_ROOT_OFFSET + RECIPE_BOOK_COUNT * RECIPE_BOOK_STRIDE;
|
||||||
|
const RT3_SAVE_WORLD_BLOCK_CHUNK_TAG: u32 = 0x000032c8;
|
||||||
|
const RT3_SAVE_WORLD_BLOCK_NEXT_CHUNK_TAG: u32 = 0x000032c9;
|
||||||
|
const RT3_SAVE_WORLD_BLOCK_LEN: usize = 0x4f2c;
|
||||||
|
const RT3_SAVE_WORLD_BLOCK_SELECTED_COMPANY_ID_RELATIVE_OFFSET: usize = 0x1d;
|
||||||
|
const RT3_SAVE_WORLD_BLOCK_SELECTED_CHAIRMAN_PROFILE_ID_RELATIVE_OFFSET: usize = 0x21;
|
||||||
const EVENT_RUNTIME_COLLECTION_METADATA_TAG: u16 = 0x4e99;
|
const EVENT_RUNTIME_COLLECTION_METADATA_TAG: u16 = 0x4e99;
|
||||||
const EVENT_RUNTIME_COLLECTION_RECORDS_TAG: u16 = 0x4e9a;
|
const EVENT_RUNTIME_COLLECTION_RECORDS_TAG: u16 = 0x4e9a;
|
||||||
const EVENT_RUNTIME_COLLECTION_CLOSE_TAG: u16 = 0x4e9b;
|
const EVENT_RUNTIME_COLLECTION_CLOSE_TAG: u16 = 0x4e9b;
|
||||||
|
|
@ -1444,6 +1449,24 @@ pub struct SmpRt3105SaveBridgePayloadProbe {
|
||||||
pub evidence: Vec<String>,
|
pub evidence: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SmpSaveWorldSelectionContextProbe {
|
||||||
|
pub profile_family: String,
|
||||||
|
pub source_kind: String,
|
||||||
|
pub semantic_family: String,
|
||||||
|
pub chunk_tag_offset: usize,
|
||||||
|
pub payload_offset: usize,
|
||||||
|
pub payload_len: usize,
|
||||||
|
pub payload_len_hex: String,
|
||||||
|
pub selected_company_id_offset: usize,
|
||||||
|
pub selected_company_id: u32,
|
||||||
|
pub selected_company_id_hex: String,
|
||||||
|
pub selected_chairman_profile_id_offset: usize,
|
||||||
|
pub selected_chairman_profile_id: u32,
|
||||||
|
pub selected_chairman_profile_id_hex: String,
|
||||||
|
pub evidence: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct SmpRt3105SaveNameTableProbe {
|
pub struct SmpRt3105SaveNameTableProbe {
|
||||||
pub profile_family: String,
|
pub profile_family: String,
|
||||||
|
|
@ -2362,6 +2385,7 @@ pub struct SmpInspectionReport {
|
||||||
pub runtime_post_span_probe: Option<SmpRuntimePostSpanProbe>,
|
pub runtime_post_span_probe: Option<SmpRuntimePostSpanProbe>,
|
||||||
pub rt3_105_post_span_bridge_probe: Option<SmpRt3105PostSpanBridgeProbe>,
|
pub rt3_105_post_span_bridge_probe: Option<SmpRt3105PostSpanBridgeProbe>,
|
||||||
pub rt3_105_save_bridge_payload_probe: Option<SmpRt3105SaveBridgePayloadProbe>,
|
pub rt3_105_save_bridge_payload_probe: Option<SmpRt3105SaveBridgePayloadProbe>,
|
||||||
|
pub save_world_selection_context_probe: Option<SmpSaveWorldSelectionContextProbe>,
|
||||||
pub rt3_105_save_name_table_probe: Option<SmpRt3105SaveNameTableProbe>,
|
pub rt3_105_save_name_table_probe: Option<SmpRt3105SaveNameTableProbe>,
|
||||||
pub rt3_105_save_named_locomotive_availability_probe:
|
pub rt3_105_save_named_locomotive_availability_probe:
|
||||||
Option<SmpRt3105SaveNamedLocomotiveAvailabilityProbe>,
|
Option<SmpRt3105SaveNamedLocomotiveAvailabilityProbe>,
|
||||||
|
|
@ -2497,6 +2521,14 @@ pub fn load_save_slice_from_report(
|
||||||
.recipe_book_summary_probe
|
.recipe_book_summary_probe
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(derive_cargo_catalog_from_recipe_book_probe);
|
.and_then(derive_cargo_catalog_from_recipe_book_probe);
|
||||||
|
let company_roster = report
|
||||||
|
.save_world_selection_context_probe
|
||||||
|
.as_ref()
|
||||||
|
.and_then(derive_selection_only_company_roster_from_save_world_probe);
|
||||||
|
let chairman_profile_table = report
|
||||||
|
.save_world_selection_context_probe
|
||||||
|
.as_ref()
|
||||||
|
.and_then(derive_selection_only_chairman_profile_table_from_save_world_probe);
|
||||||
let special_conditions_table =
|
let special_conditions_table =
|
||||||
report
|
report
|
||||||
.special_conditions_probe
|
.special_conditions_probe
|
||||||
|
|
@ -2509,6 +2541,21 @@ pub fn load_save_slice_from_report(
|
||||||
enabled_visible_labels: probe.enabled_visible_labels.clone(),
|
enabled_visible_labels: probe.enabled_visible_labels.clone(),
|
||||||
entries: probe.entries.clone(),
|
entries: probe.entries.clone(),
|
||||||
});
|
});
|
||||||
|
let mut notes = summary.notes.clone();
|
||||||
|
if let Some(probe) = &report.save_world_selection_context_probe {
|
||||||
|
notes.push(format!(
|
||||||
|
"Raw save fixed world block exposes selected_company_id={} at file offset 0x{:x}.",
|
||||||
|
probe.selected_company_id, probe.selected_company_id_offset
|
||||||
|
));
|
||||||
|
notes.push(format!(
|
||||||
|
"Raw save fixed world block exposes selected_chairman_profile_id={} at file offset 0x{:x}.",
|
||||||
|
probe.selected_chairman_profile_id, probe.selected_chairman_profile_id_offset
|
||||||
|
));
|
||||||
|
notes.push(
|
||||||
|
"Raw save inspection still does not reconstruct full company_roster or chairman_profile_table payloads; the grounded package-save path only proves selection ids and header-level collection state for those families."
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(SmpLoadedSaveSlice {
|
Ok(SmpLoadedSaveSlice {
|
||||||
file_extension_hint: summary.file_extension_hint.clone(),
|
file_extension_hint: summary.file_extension_hint.clone(),
|
||||||
|
|
@ -2522,11 +2569,11 @@ pub fn load_save_slice_from_report(
|
||||||
named_locomotive_availability_table,
|
named_locomotive_availability_table,
|
||||||
locomotive_catalog,
|
locomotive_catalog,
|
||||||
cargo_catalog,
|
cargo_catalog,
|
||||||
company_roster: None,
|
company_roster,
|
||||||
chairman_profile_table: None,
|
chairman_profile_table,
|
||||||
special_conditions_table,
|
special_conditions_table,
|
||||||
event_runtime_collection: report.event_runtime_collection_summary.clone(),
|
event_runtime_collection: report.event_runtime_collection_summary.clone(),
|
||||||
notes: summary.notes.clone(),
|
notes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2609,6 +2656,30 @@ fn derive_cargo_catalog_from_recipe_book_probe(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn derive_selection_only_company_roster_from_save_world_probe(
|
||||||
|
probe: &SmpSaveWorldSelectionContextProbe,
|
||||||
|
) -> Option<SmpLoadedCompanyRoster> {
|
||||||
|
Some(SmpLoadedCompanyRoster {
|
||||||
|
source_kind: format!("{}-company-selection-only", probe.source_kind),
|
||||||
|
semantic_family: "scenario-selected-company-context".to_string(),
|
||||||
|
observed_entry_count: 0,
|
||||||
|
selected_company_id: Some(probe.selected_company_id),
|
||||||
|
entries: Vec::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn derive_selection_only_chairman_profile_table_from_save_world_probe(
|
||||||
|
probe: &SmpSaveWorldSelectionContextProbe,
|
||||||
|
) -> Option<SmpLoadedChairmanProfileTable> {
|
||||||
|
Some(SmpLoadedChairmanProfileTable {
|
||||||
|
source_kind: format!("{}-chairman-selection-only", probe.source_kind),
|
||||||
|
semantic_family: "scenario-selected-chairman-context".to_string(),
|
||||||
|
observed_entry_count: 0,
|
||||||
|
selected_chairman_profile_id: Some(probe.selected_chairman_profile_id),
|
||||||
|
entries: Vec::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn known_cargo_slot_definition(slot_id: u32) -> Option<KnownCargoSlotDefinition> {
|
fn known_cargo_slot_definition(slot_id: u32) -> Option<KnownCargoSlotDefinition> {
|
||||||
KNOWN_CARGO_SLOT_DEFINITIONS
|
KNOWN_CARGO_SLOT_DEFINITIONS
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -5264,6 +5335,11 @@ fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option<String>) -> Sm
|
||||||
);
|
);
|
||||||
let rt3_105_save_bridge_payload_probe =
|
let rt3_105_save_bridge_payload_probe =
|
||||||
parse_rt3_105_save_bridge_payload_probe(bytes, rt3_105_post_span_bridge_probe.as_ref());
|
parse_rt3_105_save_bridge_payload_probe(bytes, rt3_105_post_span_bridge_probe.as_ref());
|
||||||
|
let save_world_selection_context_probe = parse_save_world_selection_context_probe(
|
||||||
|
bytes,
|
||||||
|
file_extension_hint.as_deref(),
|
||||||
|
container_profile.as_ref(),
|
||||||
|
);
|
||||||
let rt3_105_save_name_table_probe = parse_rt3_105_save_name_table_probe(
|
let rt3_105_save_name_table_probe = parse_rt3_105_save_name_table_probe(
|
||||||
bytes,
|
bytes,
|
||||||
file_extension_hint.as_deref(),
|
file_extension_hint.as_deref(),
|
||||||
|
|
@ -5410,6 +5486,7 @@ fn inspect_bundle_bytes(bytes: &[u8], file_extension_hint: Option<String>) -> Sm
|
||||||
runtime_post_span_probe,
|
runtime_post_span_probe,
|
||||||
rt3_105_post_span_bridge_probe,
|
rt3_105_post_span_bridge_probe,
|
||||||
rt3_105_save_bridge_payload_probe,
|
rt3_105_save_bridge_payload_probe,
|
||||||
|
save_world_selection_context_probe,
|
||||||
rt3_105_save_name_table_probe,
|
rt3_105_save_name_table_probe,
|
||||||
rt3_105_save_named_locomotive_availability_probe,
|
rt3_105_save_named_locomotive_availability_probe,
|
||||||
special_conditions_probe,
|
special_conditions_probe,
|
||||||
|
|
@ -6826,6 +6903,74 @@ fn parse_rt3_105_save_bridge_payload_probe(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_save_world_selection_context_probe(
|
||||||
|
bytes: &[u8],
|
||||||
|
file_extension_hint: Option<&str>,
|
||||||
|
container_profile: Option<&SmpContainerProfile>,
|
||||||
|
) -> Option<SmpSaveWorldSelectionContextProbe> {
|
||||||
|
if file_extension_hint != Some("gms") {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let profile = container_profile?;
|
||||||
|
let supported = matches!(
|
||||||
|
profile.profile_family.as_str(),
|
||||||
|
"rt3-classic-save-container-v1"
|
||||||
|
| "rt3-105-save-container-v1"
|
||||||
|
| "rt3-105-scenario-save-container-v1"
|
||||||
|
| "rt3-105-alt-save-container-v1"
|
||||||
|
);
|
||||||
|
if !supported {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
for chunk_tag_offset in find_u32_le_offsets(bytes, RT3_SAVE_WORLD_BLOCK_CHUNK_TAG) {
|
||||||
|
let payload_offset = chunk_tag_offset + 4;
|
||||||
|
let next_chunk_tag_offset = payload_offset.checked_add(RT3_SAVE_WORLD_BLOCK_LEN)?;
|
||||||
|
if read_u32_at(bytes, next_chunk_tag_offset) != Some(RT3_SAVE_WORLD_BLOCK_NEXT_CHUNK_TAG) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let selected_company_id_offset =
|
||||||
|
payload_offset + RT3_SAVE_WORLD_BLOCK_SELECTED_COMPANY_ID_RELATIVE_OFFSET;
|
||||||
|
let selected_chairman_profile_id_offset =
|
||||||
|
payload_offset + RT3_SAVE_WORLD_BLOCK_SELECTED_CHAIRMAN_PROFILE_ID_RELATIVE_OFFSET;
|
||||||
|
let selected_company_id = read_u32_at(bytes, selected_company_id_offset)?;
|
||||||
|
let selected_chairman_profile_id = read_u32_at(bytes, selected_chairman_profile_id_offset)?;
|
||||||
|
return Some(SmpSaveWorldSelectionContextProbe {
|
||||||
|
profile_family: profile.profile_family.clone(),
|
||||||
|
source_kind: "save-direct-world-block".to_string(),
|
||||||
|
semantic_family: "scenario-selected-company-and-chairman-context".to_string(),
|
||||||
|
chunk_tag_offset,
|
||||||
|
payload_offset,
|
||||||
|
payload_len: RT3_SAVE_WORLD_BLOCK_LEN,
|
||||||
|
payload_len_hex: format!("0x{:x}", RT3_SAVE_WORLD_BLOCK_LEN),
|
||||||
|
selected_company_id_offset,
|
||||||
|
selected_company_id,
|
||||||
|
selected_company_id_hex: format!("0x{selected_company_id:08x}"),
|
||||||
|
selected_chairman_profile_id_offset,
|
||||||
|
selected_chairman_profile_id,
|
||||||
|
selected_chairman_profile_id_hex: format!("0x{selected_chairman_profile_id:08x}"),
|
||||||
|
evidence: vec![
|
||||||
|
format!(
|
||||||
|
"chunk tag 0x32c8 at 0x{chunk_tag_offset:x} matches the fixed [world+0x04] save block"
|
||||||
|
),
|
||||||
|
format!(
|
||||||
|
"next chunk tag 0x32c9 appears at 0x{next_chunk_tag_offset:x}, matching the documented 0x4f2c payload span"
|
||||||
|
),
|
||||||
|
format!(
|
||||||
|
"selected company id comes from payload +0x{:x} ([world+0x21])",
|
||||||
|
RT3_SAVE_WORLD_BLOCK_SELECTED_COMPANY_ID_RELATIVE_OFFSET
|
||||||
|
),
|
||||||
|
format!(
|
||||||
|
"selected chairman profile id comes from payload +0x{:x} ([world+0x25])",
|
||||||
|
RT3_SAVE_WORLD_BLOCK_SELECTED_CHAIRMAN_PROFILE_ID_RELATIVE_OFFSET
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_rt3_105_save_name_table_probe(
|
fn parse_rt3_105_save_name_table_probe(
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
file_extension_hint: Option<&str>,
|
file_extension_hint: Option<&str>,
|
||||||
|
|
@ -8619,6 +8764,15 @@ fn find_u16_le_offsets(bytes: &[u8], needle: u16) -> Vec<usize> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_u32_le_offsets(bytes: &[u8], needle: u32) -> Vec<usize> {
|
||||||
|
let pattern = needle.to_le_bytes();
|
||||||
|
bytes
|
||||||
|
.windows(pattern.len())
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(offset, window)| (window == pattern).then_some(offset))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn find_next_nonzero_offset(bytes: &[u8], start: usize) -> Option<usize> {
|
fn find_next_nonzero_offset(bytes: &[u8], start: usize) -> Option<usize> {
|
||||||
bytes
|
bytes
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -13025,6 +13179,114 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parses_save_world_selection_context_probe_from_fixed_world_block() {
|
||||||
|
let mut bytes = vec![0u8; 0x8000];
|
||||||
|
let chunk_tag_offset = 0x3ceusize;
|
||||||
|
let payload_offset = chunk_tag_offset + 4;
|
||||||
|
bytes[chunk_tag_offset..chunk_tag_offset + 4]
|
||||||
|
.copy_from_slice(&RT3_SAVE_WORLD_BLOCK_CHUNK_TAG.to_le_bytes());
|
||||||
|
bytes[payload_offset + RT3_SAVE_WORLD_BLOCK_SELECTED_COMPANY_ID_RELATIVE_OFFSET
|
||||||
|
..payload_offset + RT3_SAVE_WORLD_BLOCK_SELECTED_COMPANY_ID_RELATIVE_OFFSET + 4]
|
||||||
|
.copy_from_slice(&7u32.to_le_bytes());
|
||||||
|
bytes[payload_offset + RT3_SAVE_WORLD_BLOCK_SELECTED_CHAIRMAN_PROFILE_ID_RELATIVE_OFFSET
|
||||||
|
..payload_offset
|
||||||
|
+ RT3_SAVE_WORLD_BLOCK_SELECTED_CHAIRMAN_PROFILE_ID_RELATIVE_OFFSET
|
||||||
|
+ 4]
|
||||||
|
.copy_from_slice(&9u32.to_le_bytes());
|
||||||
|
let next_chunk_offset = payload_offset + RT3_SAVE_WORLD_BLOCK_LEN;
|
||||||
|
bytes[next_chunk_offset..next_chunk_offset + 4]
|
||||||
|
.copy_from_slice(&RT3_SAVE_WORLD_BLOCK_NEXT_CHUNK_TAG.to_le_bytes());
|
||||||
|
|
||||||
|
let probe = parse_save_world_selection_context_probe(
|
||||||
|
&bytes,
|
||||||
|
Some("gms"),
|
||||||
|
Some(&SmpContainerProfile {
|
||||||
|
profile_family: "rt3-105-save-container-v1".to_string(),
|
||||||
|
profile_evidence: vec![],
|
||||||
|
is_known_profile: true,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.expect("selection-context probe should parse");
|
||||||
|
|
||||||
|
assert_eq!(probe.chunk_tag_offset, chunk_tag_offset);
|
||||||
|
assert_eq!(probe.payload_offset, payload_offset);
|
||||||
|
assert_eq!(probe.selected_company_id, 7);
|
||||||
|
assert_eq!(probe.selected_chairman_profile_id, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn loads_selection_only_company_and_chairman_context_from_save_world_probe() {
|
||||||
|
let mut report = inspect_smp_bytes(&[]);
|
||||||
|
report.save_load_summary = Some(SmpSaveLoadSummary {
|
||||||
|
file_extension_hint: Some("gms".to_string()),
|
||||||
|
container_profile_family: Some("rt3-105-save-container-v1".to_string()),
|
||||||
|
mechanism_family: "rt3-105-save-post-span-bridge-v1".to_string(),
|
||||||
|
mechanism_confidence: "mixed".to_string(),
|
||||||
|
packed_profile_kind: None,
|
||||||
|
packed_profile_family: None,
|
||||||
|
packed_profile_offset: None,
|
||||||
|
packed_profile_len: None,
|
||||||
|
map_path: None,
|
||||||
|
display_name: None,
|
||||||
|
profile_byte_0x77: None,
|
||||||
|
profile_byte_0x77_hex: None,
|
||||||
|
profile_byte_0x82: None,
|
||||||
|
profile_byte_0x82_hex: None,
|
||||||
|
profile_byte_0x97: None,
|
||||||
|
profile_byte_0x97_hex: None,
|
||||||
|
profile_byte_0xc5: None,
|
||||||
|
profile_byte_0xc5_hex: None,
|
||||||
|
trailer_family: Some("rt3-105-save-trailer-v1".to_string()),
|
||||||
|
bridge_family: Some("rt3-105-save-post-span-bridge-v1".to_string()),
|
||||||
|
candidate_table: None,
|
||||||
|
notes: vec![],
|
||||||
|
});
|
||||||
|
report.save_world_selection_context_probe = Some(SmpSaveWorldSelectionContextProbe {
|
||||||
|
profile_family: "rt3-105-save-container-v1".to_string(),
|
||||||
|
source_kind: "save-direct-world-block".to_string(),
|
||||||
|
semantic_family: "scenario-selected-company-and-chairman-context".to_string(),
|
||||||
|
chunk_tag_offset: 0x3ce,
|
||||||
|
payload_offset: 0x3d2,
|
||||||
|
payload_len: RT3_SAVE_WORLD_BLOCK_LEN,
|
||||||
|
payload_len_hex: format!("0x{:x}", RT3_SAVE_WORLD_BLOCK_LEN),
|
||||||
|
selected_company_id_offset: 0x3ef,
|
||||||
|
selected_company_id: 1,
|
||||||
|
selected_company_id_hex: "0x00000001".to_string(),
|
||||||
|
selected_chairman_profile_id_offset: 0x3f3,
|
||||||
|
selected_chairman_profile_id: 9,
|
||||||
|
selected_chairman_profile_id_hex: "0x00000009".to_string(),
|
||||||
|
evidence: vec![],
|
||||||
|
});
|
||||||
|
|
||||||
|
let slice = load_save_slice_from_report(&report).expect("save slice");
|
||||||
|
|
||||||
|
let company_roster = slice.company_roster.expect("selection-only company roster");
|
||||||
|
assert_eq!(company_roster.observed_entry_count, 0);
|
||||||
|
assert_eq!(company_roster.selected_company_id, Some(1));
|
||||||
|
assert!(company_roster.entries.is_empty());
|
||||||
|
|
||||||
|
let chairman_table = slice
|
||||||
|
.chairman_profile_table
|
||||||
|
.expect("selection-only chairman table");
|
||||||
|
assert_eq!(chairman_table.observed_entry_count, 0);
|
||||||
|
assert_eq!(chairman_table.selected_chairman_profile_id, Some(9));
|
||||||
|
assert!(chairman_table.entries.is_empty());
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
slice
|
||||||
|
.notes
|
||||||
|
.iter()
|
||||||
|
.any(|note| note.contains("selected_company_id=1"))
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
slice
|
||||||
|
.notes
|
||||||
|
.iter()
|
||||||
|
.any(|note| note.contains("selected_chairman_profile_id=9"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn classifies_rt3_105_post_span_bridge_variants() {
|
fn classifies_rt3_105_post_span_bridge_variants() {
|
||||||
let base_trailer = SmpRuntimeTrailerBlock {
|
let base_trailer = SmpRuntimeTrailerBlock {
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,10 @@ The highest-value next passes are now:
|
||||||
- checked-in save-slice documents can now carry explicit company rosters and chairman profile
|
- checked-in save-slice documents can now carry explicit company rosters and chairman profile
|
||||||
tables too, so the current company-targeted and chairman-targeted descriptor/condition batches
|
tables too, so the current company-targeted and chairman-targeted descriptor/condition batches
|
||||||
can execute from standalone save-slice fixtures without overlay snapshots when that context is
|
can execute from standalone save-slice fixtures without overlay snapshots when that context is
|
||||||
present; raw `.gms` inspection/export still does not reconstruct those company/chairman surfaces
|
present; raw `.gms` inspection/export still does not reconstruct full company/chairman rosters,
|
||||||
|
but it now does reconstruct selection-only company/chairman context from the fixed save-side
|
||||||
|
`0x32c8` world block, so overlay imports can reuse base rosters while honoring raw save-native
|
||||||
|
selected company/chairman ids
|
||||||
- a checked-in `EventEffects` export now exists at
|
- a checked-in `EventEffects` export now exists at
|
||||||
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer
|
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer
|
||||||
now exists at `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`
|
now exists at `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`
|
||||||
|
|
@ -122,7 +125,9 @@ The highest-value next passes are now:
|
||||||
/ `All Farm/Mine Production` land on bounded event-owned cargo override state, and the grounded
|
/ `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
|
named cargo-production strip `180..229` now lands on named cargo production overrides too
|
||||||
- the named cargo-price strip `106..176` remains explicit
|
- the named cargo-price strip `106..176` remains explicit
|
||||||
`blocked_evidence_blocked_descriptor` parity until descriptor ordering is pinned more strongly
|
`blocked_evidence_blocked_descriptor` parity until descriptor ordering is pinned more strongly,
|
||||||
|
but the checked-in semantic catalog now gives that band stable `Named Cargo Price Slot N`
|
||||||
|
labels instead of anonymous `Unknown Cargo Price` residue
|
||||||
- the add-building strip `503..519` is now explicitly classified as recovered shell-owned parity,
|
- the add-building strip `503..519` is now explicitly classified as recovered shell-owned parity,
|
||||||
with tracked fixture coverage, instead of generic unresolved descriptor residue
|
with tracked fixture coverage, instead of generic unresolved descriptor residue
|
||||||
- widen real packed-event executable coverage descriptor by descriptor after identity, target mask,
|
- widen real packed-event executable coverage descriptor by descriptor after identity, target mask,
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,9 @@ Implemented today:
|
||||||
those save-owned surfaces; that lets the currently supported company-targeted and
|
those save-owned surfaces; that lets the currently supported company-targeted and
|
||||||
chairman-targeted descriptor/condition batches execute from standalone save-slice fixtures
|
chairman-targeted descriptor/condition batches execute from standalone save-slice fixtures
|
||||||
without overlay snapshots when the checked-in documents include that context, while raw `.gms`
|
without overlay snapshots when the checked-in documents include that context, while raw `.gms`
|
||||||
inspection/export still leaves those company/chairman surfaces absent
|
inspection/export still leaves full company/chairman rosters absent; the grounded raw-save
|
||||||
|
tranche now covers only selection-only company/chairman context from the fixed `0x32c8` world
|
||||||
|
block, which overlay import can use to replace selected ids while preserving base rosters
|
||||||
- a checked-in `EventEffects` export now exists too at
|
- a checked-in `EventEffects` export now exists too at
|
||||||
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer
|
`artifacts/exports/rt3-1.06/event-effects-table.json`, and a checked-in semantic closure layer
|
||||||
now exists at `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`
|
now exists at `artifacts/exports/rt3-1.06/event-effects-semantic-catalog.json`
|
||||||
|
|
@ -84,7 +86,9 @@ Implemented today:
|
||||||
/ `All Farm/Mine Production` import through bounded cargo override surfaces, and the grounded
|
/ `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
|
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
|
- the named cargo-price strip `106..176` now sits on explicit
|
||||||
`blocked_evidence_blocked_descriptor` parity instead of generic unmapped-descriptor frontier
|
`blocked_evidence_blocked_descriptor` parity instead of generic unmapped-descriptor frontier;
|
||||||
|
the checked-in semantic catalog now at least gives that band stable `Named Cargo Price Slot N`
|
||||||
|
labels instead of anonymous `Unknown Cargo Price` residue
|
||||||
- the add-building strip `503..519` is now explicitly classified as recovered shell-owned parity
|
- the add-building strip `503..519` is now explicitly classified as recovered shell-owned parity
|
||||||
with tracked fixture coverage, not generic unresolved descriptor residue
|
with tracked fixture coverage, not generic unresolved descriptor residue
|
||||||
- a minimal event-owned train surface and an opaque economic-status lane now exist in runtime
|
- a minimal event-owned train surface and an opaque economic-status lane now exist in runtime
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
"grouped_effect_rows": [
|
"grouped_effect_rows": [
|
||||||
{
|
{
|
||||||
"descriptor_id": 106,
|
"descriptor_id": 106,
|
||||||
"descriptor_label": "Unknown Cargo Price",
|
"descriptor_label": "Named Cargo Price Slot 1",
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"semantic_family": "scalar_assignment"
|
"semantic_family": "scalar_assignment"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
"group_index": 0,
|
"group_index": 0,
|
||||||
"row_index": 0,
|
"row_index": 0,
|
||||||
"descriptor_id": 106,
|
"descriptor_id": 106,
|
||||||
"descriptor_label": "Unknown Cargo Price",
|
"descriptor_label": "Named Cargo Price Slot 1",
|
||||||
"target_mask_bits": 8,
|
"target_mask_bits": 8,
|
||||||
"parameter_family": "cargo_price_scalar",
|
"parameter_family": "cargo_price_scalar",
|
||||||
"opcode": 3,
|
"opcode": 3,
|
||||||
|
|
@ -84,7 +84,7 @@
|
||||||
"value_word_0x16": 0,
|
"value_word_0x16": 0,
|
||||||
"row_shape": "scalar_assignment",
|
"row_shape": "scalar_assignment",
|
||||||
"semantic_family": "scalar_assignment",
|
"semantic_family": "scalar_assignment",
|
||||||
"semantic_preview": "Set Unknown Cargo Price to 140",
|
"semantic_preview": "Set Named Cargo Price Slot 1 to 140",
|
||||||
"recovered_cargo_slot": null,
|
"recovered_cargo_slot": null,
|
||||||
"recovered_cargo_class": null,
|
"recovered_cargo_class": null,
|
||||||
"recovered_locomotive_id": null,
|
"recovered_locomotive_id": null,
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,12 @@ def locomotive_cost_label(locomotive_id: int) -> str:
|
||||||
return f"Lower-Band Locomotive Cost Slot {locomotive_id}"
|
return f"Lower-Band Locomotive Cost Slot {locomotive_id}"
|
||||||
|
|
||||||
|
|
||||||
|
def cargo_price_label(descriptor_id: int, binding: dict[str, object] | None) -> str:
|
||||||
|
if binding is not None:
|
||||||
|
return f"{binding['cargo_name']} Price"
|
||||||
|
return f"Named Cargo Price Slot {descriptor_id - 105}"
|
||||||
|
|
||||||
|
|
||||||
def load_cargo_bindings(raw_table_path: Path) -> dict[int, 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"
|
bindings_path = raw_table_path.parent / "event-effects-cargo-bindings.json"
|
||||||
if not bindings_path.exists():
|
if not bindings_path.exists():
|
||||||
|
|
@ -152,6 +158,11 @@ def classify(
|
||||||
executable_in_runtime = True
|
executable_in_runtime = True
|
||||||
elif 106 <= descriptor_id <= 176:
|
elif 106 <= descriptor_id <= 176:
|
||||||
parameter_family = "cargo_price_scalar"
|
parameter_family = "cargo_price_scalar"
|
||||||
|
binding = cargo_bindings.get(descriptor_id)
|
||||||
|
label = cargo_price_label(descriptor_id, binding)
|
||||||
|
if binding is not None:
|
||||||
|
runtime_status = "executable"
|
||||||
|
executable_in_runtime = True
|
||||||
elif 177 <= descriptor_id <= 179:
|
elif 177 <= descriptor_id <= 179:
|
||||||
parameter_family = "cargo_production_scalar"
|
parameter_family = "cargo_production_scalar"
|
||||||
runtime_status = "executable"
|
runtime_status = "executable"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue