Execute world flag packed event descriptor
This commit is contained in:
parent
5d779263d2
commit
e44e0d5ac5
8 changed files with 242 additions and 76 deletions
|
|
@ -5359,7 +5359,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn leaves_real_world_flag_descriptor_parity_only_until_key_mapping_is_grounded() {
|
||||
fn overlays_real_world_flag_descriptor_into_executable_runtime_record() {
|
||||
let base_state = state();
|
||||
let save_slice = SmpLoadedSaveSlice {
|
||||
file_extension_hint: Some("gms".to_string()),
|
||||
|
|
@ -5385,13 +5385,13 @@ mod tests {
|
|||
live_record_count: 1,
|
||||
live_entry_ids: vec![23],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 0,
|
||||
imported_runtime_record_count: 1,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 23,
|
||||
payload_offset: Some(0x7202),
|
||||
payload_offset: Some(0x7200),
|
||||
payload_len: Some(120),
|
||||
decode_status: "parity_only".to_string(),
|
||||
decode_status: "executable".to_string(),
|
||||
payload_family: "real_packed_v1".to_string(),
|
||||
trigger_kind: Some(7),
|
||||
active: None,
|
||||
|
|
@ -5405,33 +5405,133 @@ mod tests {
|
|||
grouped_effect_row_counts: vec![1, 0, 0, 0],
|
||||
grouped_effect_rows: vec![real_world_flag_row(true)],
|
||||
decoded_conditions: Vec::new(),
|
||||
decoded_actions: vec![],
|
||||
executable_import_ready: false,
|
||||
decoded_actions: vec![RuntimeEffect::SetWorldFlag {
|
||||
key: "world.disable_stock_buying_and_selling".to_string(),
|
||||
value: true,
|
||||
}],
|
||||
executable_import_ready: true,
|
||||
notes: vec![
|
||||
"decoded from grounded real 0x4e9a row framing".to_string(),
|
||||
"world-flag descriptor identity is checked in, but keyed runtime mapping remains parity-only".to_string(),
|
||||
"world-flag descriptor identity and keyed runtime mapping are checked in"
|
||||
.to_string(),
|
||||
],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let import = project_save_slice_overlay_to_runtime_state_import(
|
||||
let mut import = project_save_slice_overlay_to_runtime_state_import(
|
||||
&base_state,
|
||||
&save_slice,
|
||||
"real-world-flag-parity-overlay",
|
||||
"real-world-flag-overlay",
|
||||
None,
|
||||
)
|
||||
.expect("overlay import should project");
|
||||
|
||||
assert!(import.state.event_runtime_records.is_empty());
|
||||
assert_eq!(import.state.event_runtime_records.len(), 1);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.packed_event_collection
|
||||
.as_ref()
|
||||
.and_then(|summary| summary.records[0].import_outcome.as_deref()),
|
||||
Some("blocked_unmapped_world_descriptor")
|
||||
Some("imported")
|
||||
);
|
||||
crate::execute_step_command(
|
||||
&mut import.state,
|
||||
&crate::StepCommand::ServiceTriggerKind { trigger_kind: 7 },
|
||||
)
|
||||
.expect("trigger service should execute");
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_flags
|
||||
.get("world.disable_stock_buying_and_selling"),
|
||||
Some(&true)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlays_real_world_flag_false_variant_into_executable_runtime_record() {
|
||||
let base_state = state();
|
||||
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: 24,
|
||||
live_record_count: 1,
|
||||
live_entry_ids: vec![24],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 1,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 24,
|
||||
payload_offset: Some(0x7200),
|
||||
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(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_world_flag_row(false)],
|
||||
decoded_conditions: Vec::new(),
|
||||
decoded_actions: vec![RuntimeEffect::SetWorldFlag {
|
||||
key: "world.disable_stock_buying_and_selling".to_string(),
|
||||
value: false,
|
||||
}],
|
||||
executable_import_ready: true,
|
||||
notes: vec![
|
||||
"decoded from grounded real 0x4e9a row framing".to_string(),
|
||||
"world-flag descriptor identity and keyed runtime mapping are checked in"
|
||||
.to_string(),
|
||||
],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let mut import = project_save_slice_overlay_to_runtime_state_import(
|
||||
&base_state,
|
||||
&save_slice,
|
||||
"real-world-flag-false-overlay",
|
||||
None,
|
||||
)
|
||||
.expect("overlay import should project");
|
||||
|
||||
crate::execute_step_command(
|
||||
&mut import.state,
|
||||
&crate::StepCommand::ServiceTriggerKind { trigger_kind: 7 },
|
||||
)
|
||||
.expect("trigger service should execute");
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_flags
|
||||
.get("world.disable_stock_buying_and_selling"),
|
||||
Some(&false)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ struct RealGroupedEffectDescriptorMetadata {
|
|||
label: &'static str,
|
||||
target_mask_bits: u8,
|
||||
parameter_family: &'static str,
|
||||
runtime_key: Option<&'static str>,
|
||||
executable_in_runtime: bool,
|
||||
}
|
||||
|
||||
|
|
@ -133,6 +134,7 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Player Cash",
|
||||
target_mask_bits: 0x02,
|
||||
parameter_family: "player_finance_scalar",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
|
|
@ -140,6 +142,7 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Company Cash",
|
||||
target_mask_bits: 0x01,
|
||||
parameter_family: "company_finance_scalar",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
|
|
@ -147,6 +150,7 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Territory - Allow All",
|
||||
target_mask_bits: 0x05,
|
||||
parameter_family: "territory_access_toggle",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
|
|
@ -154,6 +158,7 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Economic Status",
|
||||
target_mask_bits: 0x08,
|
||||
parameter_family: "whole_game_state_enum",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
|
|
@ -161,6 +166,7 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Use Wartime Cargos",
|
||||
target_mask_bits: 0x08,
|
||||
parameter_family: "special_condition_scalar",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
|
|
@ -168,6 +174,7 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Turbo Diesel Availability",
|
||||
target_mask_bits: 0x08,
|
||||
parameter_family: "candidate_availability_scalar",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
|
|
@ -175,13 +182,15 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Disable Stock Buying and Selling",
|
||||
target_mask_bits: 0x08,
|
||||
parameter_family: "world_flag_toggle",
|
||||
executable_in_runtime: false,
|
||||
runtime_key: Some("world.disable_stock_buying_and_selling"),
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
descriptor_id: 9,
|
||||
label: "Confiscate All",
|
||||
target_mask_bits: 0x01,
|
||||
parameter_family: "company_confiscation_variant",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
|
|
@ -189,6 +198,7 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Deactivate Company",
|
||||
target_mask_bits: 0x01,
|
||||
parameter_family: "company_lifecycle_toggle",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
|
|
@ -196,6 +206,7 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Retire Train",
|
||||
target_mask_bits: 0x0d,
|
||||
parameter_family: "company_or_territory_asset_toggle",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
RealGroupedEffectDescriptorMetadata {
|
||||
|
|
@ -203,6 +214,7 @@ const REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA: [RealGroupedEffectDescriptorMetad
|
|||
label: "Company Track Pieces Buildable",
|
||||
target_mask_bits: 0x01,
|
||||
parameter_family: "company_build_limit_scalar",
|
||||
runtime_key: None,
|
||||
executable_in_runtime: true,
|
||||
},
|
||||
];
|
||||
|
|
@ -2801,6 +2813,10 @@ fn runtime_candidate_availability_name(label: &str) -> String {
|
|||
.to_string()
|
||||
}
|
||||
|
||||
fn runtime_world_flag_key(descriptor_metadata: RealGroupedEffectDescriptorMetadata) -> Option<String> {
|
||||
descriptor_metadata.runtime_key.map(str::to_string)
|
||||
}
|
||||
|
||||
fn decode_real_grouped_effect_actions(
|
||||
grouped_effect_rows: &[SmpLoadedPackedEventGroupedEffectRowSummary],
|
||||
compact_control: &SmpLoadedPackedEventCompactControlSummary,
|
||||
|
|
@ -2895,6 +2911,16 @@ fn decode_real_grouped_effect_action(
|
|||
});
|
||||
}
|
||||
|
||||
if descriptor_metadata.executable_in_runtime
|
||||
&& descriptor_metadata.descriptor_id == 110
|
||||
&& row.row_shape == "bool_toggle"
|
||||
{
|
||||
return Some(RuntimeEffect::SetWorldFlag {
|
||||
key: runtime_world_flag_key(descriptor_metadata)?,
|
||||
value: row.raw_scalar_value != 0,
|
||||
});
|
||||
}
|
||||
|
||||
if descriptor_metadata.executable_in_runtime
|
||||
&& descriptor_metadata.descriptor_id == 9
|
||||
&& row.row_shape == "bool_toggle"
|
||||
|
|
@ -8800,7 +8826,21 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn keeps_real_world_flag_descriptor_parity_only_with_checked_in_metadata() {
|
||||
fn looks_up_checked_in_world_flag_descriptor_metadata() {
|
||||
let metadata =
|
||||
real_grouped_effect_descriptor_metadata(110).expect("descriptor metadata should exist");
|
||||
|
||||
assert_eq!(metadata.label, "Disable Stock Buying and Selling");
|
||||
assert_eq!(metadata.parameter_family, "world_flag_toggle");
|
||||
assert_eq!(
|
||||
metadata.runtime_key,
|
||||
Some("world.disable_stock_buying_and_selling")
|
||||
);
|
||||
assert!(metadata.executable_in_runtime);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decodes_real_world_flag_descriptor_with_checked_in_runtime_key() {
|
||||
let grouped_row = build_real_grouped_effect_row(RealGroupedEffectRowSpec {
|
||||
descriptor_id: 110,
|
||||
opcode: 0,
|
||||
|
|
@ -8863,8 +8903,14 @@ mod tests {
|
|||
.as_deref(),
|
||||
Some("world_flag_toggle")
|
||||
);
|
||||
assert!(summary.records[0].decoded_actions.is_empty());
|
||||
assert!(!summary.records[0].executable_import_ready);
|
||||
assert_eq!(
|
||||
summary.records[0].decoded_actions,
|
||||
vec![RuntimeEffect::SetWorldFlag {
|
||||
key: "world.disable_stock_buying_and_selling".to_string(),
|
||||
value: true,
|
||||
}]
|
||||
);
|
||||
assert!(summary.records[0].executable_import_ready);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue