Execute world track build limit descriptor

This commit is contained in:
Jan Petykiewicz 2026-04-16 09:20:49 -07:00
commit 43c76adbf0
11 changed files with 439 additions and 9 deletions

View file

@ -532,6 +532,7 @@ fn project_save_slice_components(
disable_train_crashes_enabled: special_condition_enabled(32),
disable_train_crashes_and_breakdowns_enabled: special_condition_enabled(33),
ai_ignore_territories_at_startup_enabled: special_condition_enabled(34),
limited_track_building_amount: None,
economic_status_code: None,
absolute_counter_restore_kind: Some(
"mode-adjusted-selected-year-lane".to_string(),
@ -1034,6 +1035,9 @@ fn lower_condition_targets_in_effect(
key: key.clone(),
value: *value,
},
RuntimeEffect::SetLimitedTrackBuildingAmount { value } => {
RuntimeEffect::SetLimitedTrackBuildingAmount { value: *value }
}
RuntimeEffect::SetEconomicStatusCode { value } => {
RuntimeEffect::SetEconomicStatusCode { value: *value }
}
@ -1358,6 +1362,9 @@ fn smp_runtime_effect_to_runtime_effect(
key: key.clone(),
value: *value,
}),
RuntimeEffect::SetLimitedTrackBuildingAmount { value } => {
Ok(RuntimeEffect::SetLimitedTrackBuildingAmount { value: *value })
}
RuntimeEffect::SetEconomicStatusCode { value } => {
Ok(RuntimeEffect::SetEconomicStatusCode { value: *value })
}
@ -2099,6 +2106,7 @@ fn runtime_effect_uses_condition_true_company(effect: &RuntimeEffect) -> bool {
.iter()
.any(runtime_effect_uses_condition_true_company),
RuntimeEffect::SetWorldFlag { .. }
| RuntimeEffect::SetLimitedTrackBuildingAmount { .. }
| RuntimeEffect::SetEconomicStatusCode { .. }
| RuntimeEffect::SetPlayerCash { .. }
| RuntimeEffect::DeactivatePlayer { .. }
@ -2177,6 +2185,7 @@ fn runtime_effect_company_target_import_blocker(
runtime_effect_company_target_import_blocker(nested, company_context)
}),
RuntimeEffect::SetWorldFlag { .. }
| RuntimeEffect::SetLimitedTrackBuildingAmount { .. }
| RuntimeEffect::SetEconomicStatusCode { .. }
| RuntimeEffect::SetCandidateAvailability { .. }
| RuntimeEffect::SetSpecialCondition { .. }
@ -2799,6 +2808,32 @@ mod tests {
}
}
fn real_limited_track_building_amount_row(
value: i32,
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
group_index: 0,
row_index: 0,
descriptor_id: 122,
descriptor_label: Some("Limited Track Building Amount".to_string()),
target_mask_bits: Some(0x08),
parameter_family: Some("world_track_build_limit_scalar".to_string()),
opcode: 3,
raw_scalar_value: value,
value_byte_0x09: 0,
value_dword_0x0d: 0,
value_byte_0x11: 0,
value_byte_0x12: 0,
value_word_0x14: 0,
value_word_0x16: 0,
row_shape: "scalar_assignment".to_string(),
semantic_family: Some("scalar_assignment".to_string()),
semantic_preview: Some(format!("Set Limited Track Building Amount to {value}")),
locomotive_name: None,
notes: vec![],
}
}
fn real_special_condition_row(
value: i32,
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
@ -5462,6 +5497,81 @@ mod tests {
assert_eq!(import.state.world_restore.economic_status_code, Some(2));
}
#[test]
fn imports_real_limited_track_building_amount_descriptor_into_executable_runtime_record() {
let save_slice = SmpLoadedSaveSlice {
file_extension_hint: Some("gms".to_string()),
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
mechanism_family: "classic-save-rehydrate-v1".to_string(),
mechanism_confidence: "grounded".to_string(),
trailer_family: None,
bridge_family: None,
profile: None,
candidate_availability_table: None,
special_conditions_table: None,
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
source_kind: "packed-event-runtime-collection".to_string(),
mechanism_family: "classic-save-rehydrate-v1".to_string(),
mechanism_confidence: "grounded".to_string(),
container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
metadata_tag_offset: 0x7100,
records_tag_offset: 0x7200,
close_tag_offset: 0x7600,
packed_state_version: 0x3e9,
packed_state_version_hex: "0x000003e9".to_string(),
live_id_bound: 52,
live_record_count: 1,
live_entry_ids: vec![52],
decoded_record_count: 1,
imported_runtime_record_count: 0,
records: vec![crate::SmpLoadedPackedEventRecordSummary {
record_index: 0,
live_entry_id: 52,
payload_offset: Some(0x7202),
payload_len: Some(120),
decode_status: "parity_only".to_string(),
payload_family: "real_packed_v1".to_string(),
trigger_kind: Some(6),
active: None,
marks_collection_dirty: None,
one_shot: Some(false),
compact_control: Some(real_compact_control()),
text_bands: packed_text_bands(),
standalone_condition_row_count: 0,
standalone_condition_rows: vec![],
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![1, 0, 0, 0],
grouped_effect_rows: vec![real_limited_track_building_amount_row(18)],
decoded_conditions: Vec::new(),
decoded_actions: vec![RuntimeEffect::SetLimitedTrackBuildingAmount {
value: 18,
}],
executable_import_ready: true,
notes: vec!["decoded from grounded real 0x4e9a row framing".to_string()],
}],
}),
notes: vec![],
};
let mut import = project_save_slice_to_runtime_state_import(
&save_slice,
"real-limited-track-building-amount-save-slice",
None,
)
.expect("save-slice import should project");
execute_step_command(
&mut import.state,
&StepCommand::ServiceTriggerKind { trigger_kind: 6 },
)
.expect("real limited-track-building-amount descriptor should execute");
assert_eq!(
import.state.world_restore.limited_track_building_amount,
Some(18)
);
}
#[test]
fn overlays_real_special_condition_descriptor_into_executable_runtime_record() {
let base_state = state();