diff --git a/crates/rrt-cli/src/main.rs b/crates/rrt-cli/src/main.rs index 4dfa391..c98e4b9 100644 --- a/crates/rrt-cli/src/main.rs +++ b/crates/rrt-cli/src/main.rs @@ -4931,6 +4931,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, diff --git a/crates/rrt-fixtures/src/load.rs b/crates/rrt-fixtures/src/load.rs index 5db56fa..83df42a 100644 --- a/crates/rrt-fixtures/src/load.rs +++ b/crates/rrt-fixtures/src/load.rs @@ -280,6 +280,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -421,6 +423,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, diff --git a/crates/rrt-runtime/src/import.rs b/crates/rrt-runtime/src/import.rs index 249656b..7a19bc9 100644 --- a/crates/rrt-runtime/src/import.rs +++ b/crates/rrt-runtime/src/import.rs @@ -452,6 +452,14 @@ fn project_save_slice_components( "save_slice.cargo_catalog_present".to_string(), save_slice.cargo_catalog.is_some(), ); + world_flags.insert( + "save_slice.world_issue_37_state_present".to_string(), + save_slice.world_issue_37_state.is_some(), + ); + world_flags.insert( + "save_slice.world_economic_tuning_state_present".to_string(), + save_slice.world_economic_tuning_state.is_some(), + ); world_flags.insert( "save_slice.event_runtime_collection_present".to_string(), save_slice.event_runtime_collection.is_some(), @@ -541,6 +549,60 @@ fn project_save_slice_components( if let Some(family) = &save_slice.bridge_family { metadata.insert("save_slice.bridge_family".to_string(), family.clone()); } + if let Some(issue_state) = &save_slice.world_issue_37_state { + metadata.insert( + "save_slice.world_issue_37_source_kind".to_string(), + issue_state.source_kind.clone(), + ); + metadata.insert( + "save_slice.world_issue_37_semantic_family".to_string(), + issue_state.semantic_family.clone(), + ); + metadata.insert( + "save_slice.world_issue_37_value".to_string(), + issue_state.issue_value.to_string(), + ); + metadata.insert( + "save_slice.world_issue_37_value_hex".to_string(), + issue_state.issue_value_hex.clone(), + ); + metadata.insert( + "save_slice.world_issue_37_multiplier_raw_hex".to_string(), + issue_state.multiplier_raw_hex.clone(), + ); + metadata.insert( + "save_slice.world_issue_37_multiplier_value_f32".to_string(), + issue_state.multiplier_value_f32_text.clone(), + ); + } + if let Some(tuning_state) = &save_slice.world_economic_tuning_state { + metadata.insert( + "save_slice.world_economic_tuning_source_kind".to_string(), + tuning_state.source_kind.clone(), + ); + metadata.insert( + "save_slice.world_economic_tuning_semantic_family".to_string(), + tuning_state.semantic_family.clone(), + ); + metadata.insert( + "save_slice.world_economic_tuning_mirror_raw_hex".to_string(), + tuning_state.mirror_raw_hex.clone(), + ); + metadata.insert( + "save_slice.world_economic_tuning_mirror_value_f32".to_string(), + tuning_state.mirror_value_f32_text.clone(), + ); + metadata.insert( + "save_slice.world_economic_tuning_lane_count".to_string(), + tuning_state.lane_raw_u32.len().to_string(), + ); + for (index, value) in tuning_state.lane_value_f32_text.iter().enumerate() { + metadata.insert( + format!("save_slice.world_economic_tuning_lane_{index}_f32"), + value.clone(), + ); + } + } let save_profile = if let Some(profile) = &save_slice.profile { metadata.insert( @@ -636,7 +698,37 @@ fn project_save_slice_components( ai_ignore_territories_at_startup_enabled: special_condition_enabled(34), limited_track_building_amount: None, economic_status_code: None, - territory_access_cost: None, + territory_access_cost: None, + issue_37_value: save_slice + .world_issue_37_state + .as_ref() + .map(|state| state.issue_value), + issue_37_multiplier_raw_u32: save_slice + .world_issue_37_state + .as_ref() + .map(|state| state.multiplier_raw_u32), + issue_37_multiplier_value_f32_text: save_slice + .world_issue_37_state + .as_ref() + .map(|state| state.multiplier_value_f32_text.clone()), + economic_tuning_mirror_raw_u32: save_slice + .world_economic_tuning_state + .as_ref() + .map(|state| state.mirror_raw_u32), + economic_tuning_mirror_value_f32_text: save_slice + .world_economic_tuning_state + .as_ref() + .map(|state| state.mirror_value_f32_text.clone()), + economic_tuning_lane_raw_u32: save_slice + .world_economic_tuning_state + .as_ref() + .map(|state| state.lane_raw_u32.clone()) + .unwrap_or_default(), + economic_tuning_lane_value_f32_text: save_slice + .world_economic_tuning_state + .as_ref() + .map(|state| state.lane_value_f32_text.clone()) + .unwrap_or_default(), absolute_counter_restore_kind: Some( "mode-adjusted-selected-year-lane".to_string(), ), @@ -5378,6 +5470,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -5421,6 +5515,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -5542,6 +5638,25 @@ mod tests { (5, crate::RuntimeCargoClass::FarmMine), (9, crate::RuntimeCargoClass::Other), ])), + world_issue_37_state: Some(crate::SmpLoadedWorldIssue37State { + source_kind: "save-fixed-world-block".to_string(), + semantic_family: "world-issue-0x37".to_string(), + issue_value: 3, + issue_value_hex: "0x00000003".to_string(), + multiplier_raw_u32: 0x3d75c28f, + multiplier_raw_hex: "0x3d75c28f".to_string(), + multiplier_value_f32_text: "0.060000".to_string(), + }), + world_economic_tuning_state: Some(crate::SmpLoadedWorldEconomicTuningState { + source_kind: "save-fixed-world-block".to_string(), + semantic_family: "world-economic-tuning".to_string(), + mirror_raw_u32: 0x3f46d093, + mirror_raw_hex: "0x3f46d093".to_string(), + mirror_value_f32_text: "0.776620".to_string(), + lane_raw_u32: vec![0x3f400000, 0x3be56042], + lane_raw_hex: vec!["0x3f400000".to_string(), "0x3be56042".to_string()], + lane_value_f32_text: vec!["0.750000".to_string(), "0.007000".to_string()], + }), company_roster: None, chairman_profile_table: None, special_conditions_table: Some(crate::SmpLoadedSpecialConditionsTable { @@ -5763,6 +5878,42 @@ mod tests { .ai_ignore_territories_at_startup_enabled, Some(false) ); + assert_eq!(import.state.world_restore.issue_37_value, Some(3)); + assert_eq!( + import.state.world_restore.issue_37_multiplier_raw_u32, + Some(0x3d75c28f) + ); + assert_eq!( + import + .state + .world_restore + .issue_37_multiplier_value_f32_text + .as_deref(), + Some("0.060000") + ); + assert_eq!( + import.state.world_restore.economic_tuning_mirror_raw_u32, + Some(0x3f46d093) + ); + assert_eq!( + import + .state + .world_restore + .economic_tuning_mirror_value_f32_text + .as_deref(), + Some("0.776620") + ); + assert_eq!( + import.state.world_restore.economic_tuning_lane_raw_u32, + vec![0x3f400000, 0x3be56042] + ); + assert_eq!( + import + .state + .world_restore + .economic_tuning_lane_value_f32_text, + vec!["0.750000".to_string(), "0.007000".to_string()] + ); assert_eq!( import .state @@ -5806,6 +5957,36 @@ mod tests { import.state.special_conditions.get("Disable Cargo Economy"), Some(&0) ); + assert_eq!( + import + .state + .metadata + .get("save_slice.world_issue_37_value") + .map(String::as_str), + Some("3") + ); + assert_eq!( + import + .state + .metadata + .get("save_slice.world_economic_tuning_lane_count") + .map(String::as_str), + Some("2") + ); + assert_eq!( + import + .state + .world_flags + .get("save_slice.world_issue_37_state_present"), + Some(&true) + ); + assert_eq!( + import + .state + .world_flags + .get("save_slice.world_economic_tuning_state_present"), + Some(&true) + ); assert_eq!( import .state @@ -5870,6 +6051,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: Some(save_company_roster()), chairman_profile_table: Some(save_chairman_profile_table()), special_conditions_table: None, @@ -5944,6 +6127,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: Some(save_company_roster()), chairman_profile_table: Some(save_chairman_profile_table()), special_conditions_table: None, @@ -6045,6 +6230,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: 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(), @@ -6096,6 +6283,8 @@ mod tests { (5, crate::RuntimeCargoClass::FarmMine), (9, crate::RuntimeCargoClass::Other), ])), + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -6218,6 +6407,8 @@ mod tests { (5, crate::RuntimeCargoClass::FarmMine), (9, crate::RuntimeCargoClass::Other), ])), + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -6318,6 +6509,8 @@ mod tests { (5, crate::RuntimeCargoClass::FarmMine), (9, crate::RuntimeCargoClass::Other), ])), + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -6444,6 +6637,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -6531,6 +6726,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -6686,6 +6883,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -6931,6 +7130,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -7011,6 +7212,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -7115,6 +7318,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -7192,6 +7397,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: Some(save_company_roster()), chairman_profile_table: Some(save_chairman_profile_table()), special_conditions_table: None, @@ -7272,6 +7479,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: Some(save_company_roster()), chairman_profile_table: Some(save_chairman_profile_table()), special_conditions_table: None, @@ -7365,6 +7574,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -7474,6 +7685,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -7554,6 +7767,8 @@ mod tests { named_locomotive_availability_table: Some(save_named_locomotive_table(61)), locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -7711,6 +7926,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -7813,6 +8030,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -7892,6 +8111,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -7971,6 +8192,8 @@ mod tests { named_locomotive_availability_table: Some(save_named_locomotive_table(61)), locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -8124,6 +8347,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -8222,6 +8447,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -8299,6 +8526,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -8386,6 +8615,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -8482,6 +8713,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -8586,6 +8819,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -8679,6 +8914,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -8758,6 +8995,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -8907,6 +9146,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9066,6 +9307,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9173,6 +9416,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9261,6 +9506,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9376,6 +9623,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9485,6 +9734,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9584,6 +9835,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9679,6 +9932,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9788,6 +10043,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9882,6 +10139,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -9958,6 +10217,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -10039,6 +10300,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -10125,6 +10388,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -10211,6 +10476,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -10313,6 +10580,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -10406,6 +10675,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -10525,6 +10796,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -10664,6 +10937,8 @@ mod tests { (5, crate::RuntimeCargoClass::FarmMine), (9, crate::RuntimeCargoClass::Other), ])), + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -11194,6 +11469,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -11378,6 +11655,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -11507,6 +11786,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: Some(save_company_roster()), chairman_profile_table: Some(save_chairman_profile_table()), special_conditions_table: None, @@ -11635,6 +11916,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: Some(save_company_roster()), chairman_profile_table: Some(save_chairman_profile_table()), special_conditions_table: None, @@ -11764,6 +12047,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -11877,6 +12162,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -12065,6 +12352,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -12161,6 +12450,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -12259,6 +12550,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -12428,6 +12721,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -12580,6 +12875,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -12673,6 +12970,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -12799,6 +13098,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -12913,6 +13214,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -13082,6 +13385,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, @@ -13280,6 +13585,8 @@ mod tests { named_locomotive_availability_table: None, locomotive_catalog: None, cargo_catalog: None, + world_issue_37_state: None, + world_economic_tuning_state: None, company_roster: None, chairman_profile_table: None, special_conditions_table: None, diff --git a/crates/rrt-runtime/src/lib.rs b/crates/rrt-runtime/src/lib.rs index babe773..9b15313 100644 --- a/crates/rrt-runtime/src/lib.rs +++ b/crates/rrt-runtime/src/lib.rs @@ -71,23 +71,23 @@ pub use smp::{ SmpLoadedPackedEventConditionRowSummary, SmpLoadedPackedEventGroupedEffectRowSummary, SmpLoadedPackedEventNegativeSentinelScopeSummary, SmpLoadedPackedEventRecordSummary, SmpLoadedPackedEventTextBandSummary, SmpLoadedProfile, SmpLoadedSaveSlice, - SmpLoadedSpecialConditionsTable, SmpLocomotivePolicyFieldObservation, - SmpLocomotivePolicyFloatAlignmentCandidate, SmpLocomotivePolicyNeighborhoodProbe, - SmpPackedProfileWordLane, SmpPostSpecialConditionsScalarLane, - SmpPostSpecialConditionsScalarProbe, SmpPostTextFieldNeighborhoodProbe, - SmpPostTextFloatAlignmentCandidate, SmpPostTextGroundedFieldObservation, - SmpPreRecipeScalarPlateauLane, SmpPreRecipeScalarPlateauProbe, SmpPreamble, SmpPreambleWord, - SmpRecipeBookLineSummary, SmpRecipeBookSummaryBook, SmpRecipeBookSummaryProbe, - SmpRt3105PackedProfileBlock, SmpRt3105PackedProfileProbe, SmpRt3105PostSpanBridgeProbe, - SmpRt3105SaveBridgePayloadProbe, SmpRt3105SaveNameTableEntry, SmpRt3105SaveNameTableProbe, - SmpRuntimeAnchorCycleBlock, SmpRuntimePostSpanHeaderCandidate, SmpRuntimePostSpanProbe, - SmpRuntimeTrailerBlock, SmpSaveAnchorRunBlock, SmpSaveBootstrapBlock, - SmpSaveChairmanRecordAnalysisEntry, SmpSaveCompanyChairmanAnalysisReport, - SmpSaveCompanyRecordAnalysisEntry, SmpSaveDwordCandidate, SmpSaveLoadCandidateTableSummary, - SmpSaveLoadSummary, SmpSaveScalarCandidate, SmpSaveTaggedCollectionHeaderProbe, - SmpSaveWorldEconomicTuningProbe, SmpSaveWorldIssue37Probe, SmpSaveWorldSelectionRoleAnalysis, - SmpSaveWorldSelectionRoleAnalysisEntry, SmpSecondaryVariantProbe, SmpSharedHeader, - SmpSpecialConditionEntry, SmpSpecialConditionsProbe, + SmpLoadedSpecialConditionsTable, SmpLoadedWorldEconomicTuningState, SmpLoadedWorldIssue37State, + SmpLocomotivePolicyFieldObservation, SmpLocomotivePolicyFloatAlignmentCandidate, + SmpLocomotivePolicyNeighborhoodProbe, SmpPackedProfileWordLane, + SmpPostSpecialConditionsScalarLane, SmpPostSpecialConditionsScalarProbe, + SmpPostTextFieldNeighborhoodProbe, SmpPostTextFloatAlignmentCandidate, + SmpPostTextGroundedFieldObservation, SmpPreRecipeScalarPlateauLane, + SmpPreRecipeScalarPlateauProbe, SmpPreamble, SmpPreambleWord, SmpRecipeBookLineSummary, + SmpRecipeBookSummaryBook, SmpRecipeBookSummaryProbe, SmpRt3105PackedProfileBlock, + SmpRt3105PackedProfileProbe, SmpRt3105PostSpanBridgeProbe, SmpRt3105SaveBridgePayloadProbe, + SmpRt3105SaveNameTableEntry, SmpRt3105SaveNameTableProbe, SmpRuntimeAnchorCycleBlock, + SmpRuntimePostSpanHeaderCandidate, SmpRuntimePostSpanProbe, SmpRuntimeTrailerBlock, + SmpSaveAnchorRunBlock, SmpSaveBootstrapBlock, SmpSaveChairmanRecordAnalysisEntry, + SmpSaveCompanyChairmanAnalysisReport, SmpSaveCompanyRecordAnalysisEntry, SmpSaveDwordCandidate, + SmpSaveLoadCandidateTableSummary, SmpSaveLoadSummary, SmpSaveScalarCandidate, + SmpSaveTaggedCollectionHeaderProbe, SmpSaveWorldEconomicTuningProbe, SmpSaveWorldIssue37Probe, + SmpSaveWorldSelectionRoleAnalysis, SmpSaveWorldSelectionRoleAnalysisEntry, + SmpSecondaryVariantProbe, SmpSharedHeader, SmpSpecialConditionEntry, SmpSpecialConditionsProbe, inspect_save_company_and_chairman_analysis_bytes, inspect_save_company_and_chairman_analysis_file, inspect_smp_bytes, inspect_smp_file, load_save_slice_file, load_save_slice_from_report, diff --git a/crates/rrt-runtime/src/runtime.rs b/crates/rrt-runtime/src/runtime.rs index 56e388e..2768110 100644 --- a/crates/rrt-runtime/src/runtime.rs +++ b/crates/rrt-runtime/src/runtime.rs @@ -859,6 +859,20 @@ pub struct RuntimeWorldRestoreState { #[serde(default)] pub territory_access_cost: Option, #[serde(default)] + pub issue_37_value: Option, + #[serde(default)] + pub issue_37_multiplier_raw_u32: Option, + #[serde(default)] + pub issue_37_multiplier_value_f32_text: Option, + #[serde(default)] + pub economic_tuning_mirror_raw_u32: Option, + #[serde(default)] + pub economic_tuning_mirror_value_f32_text: Option, + #[serde(default)] + pub economic_tuning_lane_raw_u32: Vec, + #[serde(default)] + pub economic_tuning_lane_value_f32_text: Vec, + #[serde(default)] pub absolute_counter_restore_kind: Option, #[serde(default)] pub absolute_counter_adjustment_context: Option, @@ -2193,6 +2207,13 @@ mod tests { limited_track_building_amount: None, economic_status_code: None, territory_access_cost: None, + issue_37_value: None, + issue_37_multiplier_raw_u32: None, + issue_37_multiplier_value_f32_text: None, + economic_tuning_mirror_raw_u32: None, + economic_tuning_mirror_value_f32_text: None, + economic_tuning_lane_raw_u32: Vec::new(), + economic_tuning_lane_value_f32_text: Vec::new(), absolute_counter_restore_kind: Some( "mode-adjusted-selected-year-lane".to_string(), ), diff --git a/crates/rrt-runtime/src/smp.rs b/crates/rrt-runtime/src/smp.rs index 55c9905..79f7faa 100644 --- a/crates/rrt-runtime/src/smp.rs +++ b/crates/rrt-runtime/src/smp.rs @@ -2145,6 +2145,29 @@ pub struct SmpLoadedCargoCatalog { pub entries: Vec, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpLoadedWorldIssue37State { + pub source_kind: String, + pub semantic_family: String, + pub issue_value: u32, + pub issue_value_hex: String, + pub multiplier_raw_u32: u32, + pub multiplier_raw_hex: String, + pub multiplier_value_f32_text: String, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpLoadedWorldEconomicTuningState { + pub source_kind: String, + pub semantic_family: String, + pub mirror_raw_u32: u32, + pub mirror_raw_hex: String, + pub mirror_value_f32_text: String, + pub lane_raw_u32: Vec, + pub lane_raw_hex: Vec, + pub lane_value_f32_text: Vec, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SmpLoadedCompanyRosterEntry { pub company_id: u32, @@ -2524,6 +2547,10 @@ pub struct SmpLoadedSaveSlice { #[serde(default)] pub cargo_catalog: Option, #[serde(default)] + pub world_issue_37_state: Option, + #[serde(default)] + pub world_economic_tuning_state: Option, + #[serde(default)] pub company_roster: Option, #[serde(default)] pub chairman_profile_table: Option, @@ -2704,6 +2731,14 @@ pub fn load_save_slice_from_report( .recipe_book_summary_probe .as_ref() .and_then(derive_cargo_catalog_from_recipe_book_probe); + let world_issue_37_state = report + .save_world_issue_37_probe + .as_ref() + .map(derive_loaded_world_issue_37_state_from_probe); + let world_economic_tuning_state = report + .save_world_economic_tuning_probe + .as_ref() + .map(derive_loaded_world_economic_tuning_state_from_probe); let company_roster = report.save_company_roster_probe.clone().or_else(|| { report .save_world_selection_context_probe @@ -2837,6 +2872,8 @@ pub fn load_save_slice_from_report( named_locomotive_availability_table, locomotive_catalog, cargo_catalog, + world_issue_37_state, + world_economic_tuning_state, company_roster, chairman_profile_table, special_conditions_table, @@ -3211,6 +3248,43 @@ fn derive_cargo_catalog_from_recipe_book_probe( }) } +fn derive_loaded_world_issue_37_state_from_probe( + probe: &SmpSaveWorldIssue37Probe, +) -> SmpLoadedWorldIssue37State { + SmpLoadedWorldIssue37State { + source_kind: probe.source_kind.clone(), + semantic_family: probe.semantic_family.clone(), + issue_value: probe.issue_value_lane.raw_u32, + issue_value_hex: probe.issue_value_lane.raw_u32_hex.clone(), + multiplier_raw_u32: probe.multiplier_lane.raw_u32, + multiplier_raw_hex: probe.multiplier_lane.raw_u32_hex.clone(), + multiplier_value_f32_text: format!("{:.6}", probe.multiplier_lane.value_f32), + } +} + +fn derive_loaded_world_economic_tuning_state_from_probe( + probe: &SmpSaveWorldEconomicTuningProbe, +) -> SmpLoadedWorldEconomicTuningState { + SmpLoadedWorldEconomicTuningState { + source_kind: probe.source_kind.clone(), + semantic_family: probe.semantic_family.clone(), + mirror_raw_u32: probe.mirror_lane.raw_u32, + mirror_raw_hex: probe.mirror_lane.raw_u32_hex.clone(), + mirror_value_f32_text: format!("{:.6}", probe.mirror_lane.value_f32), + lane_raw_u32: probe.tuning_lanes.iter().map(|lane| lane.raw_u32).collect(), + lane_raw_hex: probe + .tuning_lanes + .iter() + .map(|lane| lane.raw_u32_hex.clone()) + .collect(), + lane_value_f32_text: probe + .tuning_lanes + .iter() + .map(|lane| format!("{:.6}", lane.value_f32)) + .collect(), + } +} + fn derive_selection_only_company_roster_from_save_world_probe( probe: &SmpSaveWorldSelectionContextProbe, header_probe: Option<&SmpSaveTaggedCollectionHeaderProbe>, @@ -15010,6 +15084,73 @@ mod tests { chairman_role_gate_bytes: vec![2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], evidence: vec![], }); + report.save_world_issue_37_probe = Some(SmpSaveWorldIssue37Probe { + profile_family: "rt3-105-save-container-v1".to_string(), + source_kind: "save-direct-world-block".to_string(), + semantic_family: "scenario-save-world-issue-0x37".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), + issue_value_lane: SmpSaveDwordCandidate { + label: "issue_0x37_value".to_string(), + relative_offset: 0x29, + relative_offset_hex: "0x29".to_string(), + raw_u32: 3, + raw_u32_hex: "0x00000003".to_string(), + value_i32: 3, + value_f32: f32::from_bits(3), + }, + multiplier_lane: SmpSaveDwordCandidate { + label: "issue_0x37_multiplier".to_string(), + relative_offset: 0x25, + relative_offset_hex: "0x25".to_string(), + raw_u32: 0x3d75c28f, + raw_u32_hex: "0x3d75c28f".to_string(), + value_i32: 1031127695, + value_f32: 0.06, + }, + evidence: vec![], + }); + report.save_world_economic_tuning_probe = Some(SmpSaveWorldEconomicTuningProbe { + profile_family: "rt3-105-save-container-v1".to_string(), + source_kind: "save-direct-world-block".to_string(), + semantic_family: "scenario-save-world-economic-tuning".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), + mirror_lane: SmpSaveDwordCandidate { + label: "economic_tuning_mirror_lane_0".to_string(), + relative_offset: 0xbda, + relative_offset_hex: "0xbda".to_string(), + raw_u32: 0x3f46d093, + raw_u32_hex: "0x3f46d093".to_string(), + value_i32: 1061605523, + value_f32: 0.7766201, + }, + tuning_lanes: vec![ + SmpSaveDwordCandidate { + label: "economic_tuning_lane_0".to_string(), + relative_offset: 0xbde, + relative_offset_hex: "0xbde".to_string(), + raw_u32: 0x3f400000, + raw_u32_hex: "0x3f400000".to_string(), + value_i32: 1061158912, + value_f32: 0.75, + }, + SmpSaveDwordCandidate { + label: "economic_tuning_lane_1".to_string(), + relative_offset: 0xbe2, + relative_offset_hex: "0xbe2".to_string(), + raw_u32: 0x3be56042, + raw_u32_hex: "0x3be56042".to_string(), + value_i32: 1004888130, + value_f32: 0.007, + }, + ], + evidence: vec![], + }); report.save_company_collection_header_probe = Some(SmpSaveTaggedCollectionHeaderProbe { profile_family: "rt3-105-save-container-v1".to_string(), source_kind: "save-company-tagged-header-counts".to_string(), @@ -15077,6 +15218,21 @@ mod tests { assert_eq!(chairman_table.observed_entry_count, 2); assert_eq!(chairman_table.selected_chairman_profile_id, Some(9)); assert!(chairman_table.entries.is_empty()); + let issue_37_state = slice + .world_issue_37_state + .expect("world issue-0x37 state should load"); + assert_eq!(issue_37_state.issue_value, 3); + assert_eq!(issue_37_state.multiplier_raw_hex, "0x3d75c28f"); + assert_eq!(issue_37_state.multiplier_value_f32_text, "0.060000"); + let tuning_state = slice + .world_economic_tuning_state + .expect("world economic tuning state should load"); + assert_eq!(tuning_state.mirror_raw_hex, "0x3f46d093"); + assert_eq!(tuning_state.mirror_value_f32_text, "0.776620"); + assert_eq!( + tuning_state.lane_value_f32_text, + vec!["0.750000", "0.007000"] + ); assert!( slice @@ -15090,6 +15246,12 @@ mod tests { .iter() .any(|note| note.contains("selected_chairman_profile_id=9")) ); + assert!( + slice + .notes + .iter() + .any(|note| note.contains("grounded issue-0x37 pair: value=3")) + ); assert!( slice .notes diff --git a/fixtures/runtime/packed-event-cargo-catalog-save-slice-fixture.json b/fixtures/runtime/packed-event-cargo-catalog-save-slice-fixture.json index 81c7759..dff85e9 100644 --- a/fixtures/runtime/packed-event-cargo-catalog-save-slice-fixture.json +++ b/fixtures/runtime/packed-event-cargo-catalog-save-slice-fixture.json @@ -20,7 +20,7 @@ "tick_slot": 1 }, "calendar_projection_is_placeholder": true, - "world_flag_count": 8, + "world_flag_count": 10, "cargo_catalog_count": 11, "packed_event_collection_present": false, "event_runtime_record_count": 0 diff --git a/fixtures/runtime/packed-event-chairman-condition-overlay-fixture.json b/fixtures/runtime/packed-event-chairman-condition-overlay-fixture.json index d3eb095..c884859 100644 --- a/fixtures/runtime/packed-event-chairman-condition-overlay-fixture.json +++ b/fixtures/runtime/packed-event-chairman-condition-overlay-fixture.json @@ -27,7 +27,7 @@ "packed_event_decoded_record_count": 1, "packed_event_imported_runtime_record_count": 1, "event_runtime_record_count": 1, - "world_flag_count": 10, + "world_flag_count": 12, "total_event_record_service_count": 1, "total_trigger_dispatch_count": 1 }, diff --git a/fixtures/runtime/packed-event-company-governance-condition-overlay-fixture.json b/fixtures/runtime/packed-event-company-governance-condition-overlay-fixture.json index 90823a8..e2b6165 100644 --- a/fixtures/runtime/packed-event-company-governance-condition-overlay-fixture.json +++ b/fixtures/runtime/packed-event-company-governance-condition-overlay-fixture.json @@ -27,7 +27,7 @@ "packed_event_decoded_record_count": 1, "packed_event_imported_runtime_record_count": 1, "event_runtime_record_count": 1, - "world_flag_count": 10, + "world_flag_count": 12, "total_event_record_service_count": 1, "total_trigger_dispatch_count": 1 }, diff --git a/fixtures/runtime/packed-event-selective-import-overlay-fixture.json b/fixtures/runtime/packed-event-selective-import-overlay-fixture.json index 1ed4dc0..be3a88b 100644 --- a/fixtures/runtime/packed-event-selective-import-overlay-fixture.json +++ b/fixtures/runtime/packed-event-selective-import-overlay-fixture.json @@ -21,7 +21,7 @@ }, "calendar_projection_source": "base-snapshot-preserved", "calendar_projection_is_placeholder": false, - "world_flag_count": 10, + "world_flag_count": 12, "company_count": 1, "packed_event_collection_present": true, "packed_event_record_count": 2, diff --git a/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json b/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json index ee88925..7e14235 100644 --- a/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json +++ b/fixtures/runtime/packed-event-world-scalar-condition-parity-save-slice-fixture.json @@ -26,7 +26,7 @@ "cargo_catalog_count": 11, "event_runtime_record_count": 2, "cargo_production_override_count": 3, - "world_flag_count": 9, + "world_flag_count": 11, "total_event_record_service_count": 2, "total_trigger_dispatch_count": 2 }, diff --git a/fixtures/runtime/packed-event-world-scalar-condition-save-slice-fixture.json b/fixtures/runtime/packed-event-world-scalar-condition-save-slice-fixture.json index a52036d..9a619ca 100644 --- a/fixtures/runtime/packed-event-world-scalar-condition-save-slice-fixture.json +++ b/fixtures/runtime/packed-event-world-scalar-condition-save-slice-fixture.json @@ -29,7 +29,7 @@ "cargo_production_override_count": 3, "world_restore_limited_track_building_amount": 18, "world_restore_territory_access_cost": 750000, - "world_flag_count": 9, + "world_flag_count": 11, "total_event_record_service_count": 2, "total_trigger_dispatch_count": 2 },