Close out EventEffects descriptor metadata
This commit is contained in:
parent
a63de904fa
commit
3dbcec688f
15 changed files with 7156 additions and 23 deletions
|
|
@ -2683,6 +2683,13 @@ fn determine_packed_event_import_outcome(
|
|||
return "blocked_unmapped_ordinary_condition".to_string();
|
||||
}
|
||||
}
|
||||
if record
|
||||
.grouped_effect_rows
|
||||
.iter()
|
||||
.any(real_grouped_row_is_shell_owned_descriptor_family)
|
||||
{
|
||||
return "blocked_shell_owned_descriptor".to_string();
|
||||
}
|
||||
if record
|
||||
.grouped_effect_rows
|
||||
.iter()
|
||||
|
|
@ -2779,6 +2786,13 @@ fn real_grouped_row_is_world_state_family(
|
|||
})
|
||||
}
|
||||
|
||||
fn real_grouped_row_is_shell_owned_descriptor_family(
|
||||
row: &SmpLoadedPackedEventGroupedEffectRowSummary,
|
||||
) -> bool {
|
||||
crate::smp::grouped_effect_descriptor_runtime_status_name(row.descriptor_id)
|
||||
.is_some_and(|status| status == "shell_owned")
|
||||
}
|
||||
|
||||
fn packed_record_company_target_import_blocker(
|
||||
record: &SmpLoadedPackedEventRecordSummary,
|
||||
company_context: &ImportRuntimeContext,
|
||||
|
|
@ -3661,6 +3675,69 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
fn real_credit_rating_row(value: i32) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||
group_index: 0,
|
||||
row_index: 0,
|
||||
descriptor_id: 56,
|
||||
descriptor_label: Some("Credit Rating".to_string()),
|
||||
target_mask_bits: Some(0x0b),
|
||||
parameter_family: Some("company_governance_scalar".to_string()),
|
||||
grouped_target_subject: Some("company".to_string()),
|
||||
grouped_target_scope: Some("selected_company".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 Credit Rating to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn real_merger_premium_shell_row(
|
||||
value: i32,
|
||||
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||
crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||
group_index: 0,
|
||||
row_index: 0,
|
||||
descriptor_id: 58,
|
||||
descriptor_label: Some("Merger Premium".to_string()),
|
||||
target_mask_bits: Some(0x0b),
|
||||
parameter_family: Some("company_finance_shell_scalar".to_string()),
|
||||
grouped_target_subject: Some("company".to_string()),
|
||||
grouped_target_scope: Some("selected_company".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 Merger Premium to {value}")),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
recovered_locomotive_id: None,
|
||||
locomotive_name: None,
|
||||
notes: vec![
|
||||
"descriptor is recovered in the checked-in effect table as shell_owned parity"
|
||||
.to_string(),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
fn real_deactivate_player_row(
|
||||
enabled: bool,
|
||||
) -> crate::SmpLoadedPackedEventGroupedEffectRowSummary {
|
||||
|
|
@ -6053,6 +6130,176 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leaves_recovered_shell_owned_descriptor_rows_on_explicit_shell_owned_frontier() {
|
||||
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,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
company_roster: Some(save_company_roster()),
|
||||
chairman_profile_table: Some(save_chairman_profile_table()),
|
||||
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: 8,
|
||||
live_record_count: 1,
|
||||
live_entry_ids: vec![8],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 0,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 8,
|
||||
payload_offset: Some(0x7202),
|
||||
payload_len: Some(120),
|
||||
decode_status: "parity_only".to_string(),
|
||||
payload_family: "real_packed_v1".to_string(),
|
||||
trigger_kind: Some(7),
|
||||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: Some(true),
|
||||
compact_control: Some(real_compact_control_without_symbolic_company_scope()),
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 0,
|
||||
standalone_condition_rows: Vec::new(),
|
||||
negative_sentinel_scope: None,
|
||||
grouped_effect_row_counts: vec![1, 0, 0, 0],
|
||||
grouped_effect_rows: vec![real_merger_premium_shell_row(25)],
|
||||
decoded_conditions: Vec::new(),
|
||||
decoded_actions: Vec::new(),
|
||||
executable_import_ready: false,
|
||||
notes: vec!["synthetic shell-owned descriptor test record".to_string()],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let import = project_save_slice_to_runtime_state_import(
|
||||
&save_slice,
|
||||
"packed-events-shell-owned-descriptor-frontier",
|
||||
None,
|
||||
)
|
||||
.expect("save slice should project");
|
||||
|
||||
assert!(import.state.event_runtime_records.is_empty());
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.packed_event_collection
|
||||
.as_ref()
|
||||
.and_then(|summary| summary.records[0].import_outcome.as_deref()),
|
||||
Some("blocked_shell_owned_descriptor")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imports_credit_rating_descriptor_from_save_slice_company_context() {
|
||||
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,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
company_roster: Some(save_company_roster()),
|
||||
chairman_profile_table: Some(save_chairman_profile_table()),
|
||||
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: 9,
|
||||
live_record_count: 1,
|
||||
live_entry_ids: vec![9],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 0,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 9,
|
||||
payload_offset: Some(0x7202),
|
||||
payload_len: Some(120),
|
||||
decode_status: "executable".to_string(),
|
||||
payload_family: "real_packed_v1".to_string(),
|
||||
trigger_kind: Some(7),
|
||||
active: None,
|
||||
marks_collection_dirty: None,
|
||||
one_shot: Some(true),
|
||||
compact_control: Some(real_compact_control_without_symbolic_company_scope()),
|
||||
text_bands: packed_text_bands(),
|
||||
standalone_condition_row_count: 0,
|
||||
standalone_condition_rows: Vec::new(),
|
||||
negative_sentinel_scope: None,
|
||||
grouped_effect_row_counts: vec![1, 0, 0, 0],
|
||||
grouped_effect_rows: vec![real_credit_rating_row(640)],
|
||||
decoded_conditions: Vec::new(),
|
||||
decoded_actions: vec![RuntimeEffect::SetCompanyGovernanceScalar {
|
||||
target: RuntimeCompanyTarget::SelectedCompany,
|
||||
metric: crate::RuntimeCompanyMetric::CreditRating,
|
||||
value: 640,
|
||||
}],
|
||||
executable_import_ready: true,
|
||||
notes: vec!["synthetic governance descriptor test record".to_string()],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let import = project_save_slice_to_runtime_state_import(
|
||||
&save_slice,
|
||||
"packed-events-credit-rating-descriptor",
|
||||
None,
|
||||
)
|
||||
.expect("save slice should project");
|
||||
|
||||
assert_eq!(import.state.event_runtime_records.len(), 1);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.event_runtime_records
|
||||
.first()
|
||||
.map(|record| record.effects.clone()),
|
||||
Some(vec![RuntimeEffect::SetCompanyGovernanceScalar {
|
||||
target: RuntimeCompanyTarget::SelectedCompany,
|
||||
metric: crate::RuntimeCompanyMetric::CreditRating,
|
||||
value: 640,
|
||||
}])
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.packed_event_collection
|
||||
.as_ref()
|
||||
.and_then(|summary| summary.records[0].import_outcome.as_deref()),
|
||||
Some("imported")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blocks_scalar_locomotive_availability_rows_without_catalog_context() {
|
||||
let save_slice = SmpLoadedSaveSlice {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue