Implement governance issue packed event conditions
This commit is contained in:
parent
3a88fd3347
commit
5c2156bcbf
10 changed files with 1048 additions and 13 deletions
|
|
@ -9661,6 +9661,262 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imports_investor_confidence_condition_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: 73,
|
||||
live_record_count: 1,
|
||||
live_entry_ids: vec![73],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 0,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 73,
|
||||
payload_offset: Some(0x7202),
|
||||
payload_len: Some(136),
|
||||
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(false),
|
||||
compact_control: Some(real_compact_control()),
|
||||
text_bands: vec![],
|
||||
standalone_condition_row_count: 1,
|
||||
standalone_condition_rows: vec![
|
||||
crate::SmpLoadedPackedEventConditionRowSummary {
|
||||
row_index: 0,
|
||||
raw_condition_id: 2366,
|
||||
subtype: 4,
|
||||
flag_bytes: {
|
||||
let mut bytes = vec![0; 25];
|
||||
bytes[0..4].copy_from_slice(&37_i32.to_le_bytes());
|
||||
bytes
|
||||
},
|
||||
candidate_name: None,
|
||||
comparator: Some("eq".to_string()),
|
||||
metric: Some("Investor Confidence".to_string()),
|
||||
semantic_family: Some("numeric_threshold".to_string()),
|
||||
semantic_preview: Some("Test Investor Confidence == 37".to_string()),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
requires_candidate_name_binding: false,
|
||||
notes: vec![],
|
||||
},
|
||||
],
|
||||
negative_sentinel_scope: Some(company_negative_sentinel_scope(
|
||||
RuntimeCompanyConditionTestScope::SelectedCompanyOnly,
|
||||
)),
|
||||
grouped_effect_row_counts: vec![1, 0, 0, 0],
|
||||
grouped_effect_rows: vec![real_world_flag_row(
|
||||
110,
|
||||
"Disable Stock Buying and Selling",
|
||||
true,
|
||||
)],
|
||||
decoded_conditions: vec![RuntimeCondition::CompanyNumericThreshold {
|
||||
target: RuntimeCompanyTarget::ConditionTrueCompany,
|
||||
metric: crate::RuntimeCompanyMetric::InvestorConfidence,
|
||||
comparator: RuntimeConditionComparator::Eq,
|
||||
value: 37,
|
||||
}],
|
||||
decoded_actions: vec![RuntimeEffect::SetWorldFlag {
|
||||
key: "world.investor_confidence_condition_imported".to_string(),
|
||||
value: true,
|
||||
}],
|
||||
executable_import_ready: true,
|
||||
notes: vec![
|
||||
"investor confidence condition gates a world-side effect".to_string(),
|
||||
],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let mut import = project_save_slice_to_runtime_state_import(
|
||||
&save_slice,
|
||||
"company-investor-confidence-condition",
|
||||
None,
|
||||
)
|
||||
.expect("save-slice import should project");
|
||||
|
||||
assert_eq!(import.state.event_runtime_records.len(), 1);
|
||||
assert_eq!(
|
||||
import.state.event_runtime_records[0].conditions,
|
||||
vec![RuntimeCondition::CompanyNumericThreshold {
|
||||
target: RuntimeCompanyTarget::SelectedCompany,
|
||||
metric: crate::RuntimeCompanyMetric::InvestorConfidence,
|
||||
comparator: RuntimeConditionComparator::Eq,
|
||||
value: 37,
|
||||
}]
|
||||
);
|
||||
|
||||
crate::execute_step_command(
|
||||
&mut import.state,
|
||||
&crate::StepCommand::ServiceTriggerKind { trigger_kind: 7 },
|
||||
)
|
||||
.expect("investor-confidence trigger should execute");
|
||||
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_flags
|
||||
.get("world.investor_confidence_condition_imported"),
|
||||
Some(&true)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imports_management_attitude_condition_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: 74,
|
||||
live_record_count: 1,
|
||||
live_entry_ids: vec![74],
|
||||
decoded_record_count: 1,
|
||||
imported_runtime_record_count: 0,
|
||||
records: vec![crate::SmpLoadedPackedEventRecordSummary {
|
||||
record_index: 0,
|
||||
live_entry_id: 74,
|
||||
payload_offset: Some(0x7202),
|
||||
payload_len: Some(136),
|
||||
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(false),
|
||||
compact_control: Some(real_compact_control()),
|
||||
text_bands: vec![],
|
||||
standalone_condition_row_count: 1,
|
||||
standalone_condition_rows: vec![
|
||||
crate::SmpLoadedPackedEventConditionRowSummary {
|
||||
row_index: 0,
|
||||
raw_condition_id: 2369,
|
||||
subtype: 4,
|
||||
flag_bytes: {
|
||||
let mut bytes = vec![0; 25];
|
||||
bytes[0..4].copy_from_slice(&58_i32.to_le_bytes());
|
||||
bytes
|
||||
},
|
||||
candidate_name: None,
|
||||
comparator: Some("eq".to_string()),
|
||||
metric: Some("Management Attitude".to_string()),
|
||||
semantic_family: Some("numeric_threshold".to_string()),
|
||||
semantic_preview: Some("Test Management Attitude == 58".to_string()),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
requires_candidate_name_binding: false,
|
||||
notes: vec![],
|
||||
},
|
||||
],
|
||||
negative_sentinel_scope: Some(company_negative_sentinel_scope(
|
||||
RuntimeCompanyConditionTestScope::SelectedCompanyOnly,
|
||||
)),
|
||||
grouped_effect_row_counts: vec![1, 0, 0, 0],
|
||||
grouped_effect_rows: vec![real_world_flag_row(
|
||||
110,
|
||||
"Disable Stock Buying and Selling",
|
||||
true,
|
||||
)],
|
||||
decoded_conditions: vec![RuntimeCondition::CompanyNumericThreshold {
|
||||
target: RuntimeCompanyTarget::ConditionTrueCompany,
|
||||
metric: crate::RuntimeCompanyMetric::ManagementAttitude,
|
||||
comparator: RuntimeConditionComparator::Eq,
|
||||
value: 58,
|
||||
}],
|
||||
decoded_actions: vec![RuntimeEffect::SetWorldFlag {
|
||||
key: "world.management_attitude_condition_imported".to_string(),
|
||||
value: true,
|
||||
}],
|
||||
executable_import_ready: true,
|
||||
notes: vec![
|
||||
"management attitude condition gates a world-side effect".to_string(),
|
||||
],
|
||||
}],
|
||||
}),
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
let mut import = project_save_slice_to_runtime_state_import(
|
||||
&save_slice,
|
||||
"company-management-attitude-condition",
|
||||
None,
|
||||
)
|
||||
.expect("save-slice import should project");
|
||||
|
||||
assert_eq!(import.state.event_runtime_records.len(), 1);
|
||||
assert_eq!(
|
||||
import.state.event_runtime_records[0].conditions,
|
||||
vec![RuntimeCondition::CompanyNumericThreshold {
|
||||
target: RuntimeCompanyTarget::SelectedCompany,
|
||||
metric: crate::RuntimeCompanyMetric::ManagementAttitude,
|
||||
comparator: RuntimeConditionComparator::Eq,
|
||||
value: 58,
|
||||
}]
|
||||
);
|
||||
|
||||
crate::execute_step_command(
|
||||
&mut import.state,
|
||||
&crate::StepCommand::ServiceTriggerKind { trigger_kind: 7 },
|
||||
)
|
||||
.expect("management-attitude trigger should execute");
|
||||
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_flags
|
||||
.get("world.management_attitude_condition_imported"),
|
||||
Some(&true)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlays_recovered_world_toggle_batch_into_executable_runtime_record() {
|
||||
let base_state = state();
|
||||
|
|
|
|||
|
|
@ -350,6 +350,10 @@ const REAL_CHAIRMAN_CASH_CONDITION_ID: i32 = 2218;
|
|||
const REAL_CHAIRMAN_HOLDINGS_TOTAL_CONDITION_ID: i32 = 2239;
|
||||
const REAL_CHAIRMAN_NET_WORTH_CONDITION_ID: i32 = 2240;
|
||||
const REAL_CHAIRMAN_PURCHASING_POWER_CONDITION_ID: i32 = 1247;
|
||||
const REAL_INVESTOR_CONFIDENCE_CONDITION_ID: i32 = 2366;
|
||||
const REAL_CREDIT_RATING_CONDITION_ID: i32 = 2367;
|
||||
const REAL_PRIME_RATE_CONDITION_ID: i32 = 2368;
|
||||
const REAL_MANAGEMENT_ATTITUDE_CONDITION_ID: i32 = 2369;
|
||||
const REAL_BOOK_VALUE_PER_SHARE_CONDITION_ID: i32 = 2620;
|
||||
const REAL_CARGO_PRODUCTION_CONDITION_TEMPLATE_ID: i32 = 200;
|
||||
const REAL_NAMED_LOCOMOTIVE_AVAILABILITY_CONDITION_ID: i32 = 2422;
|
||||
|
|
@ -361,7 +365,7 @@ const REAL_OTHER_CARGO_PRODUCTION_TOTAL_CONDITION_ID: i32 = 2421;
|
|||
const REAL_LIMITED_TRACK_BUILDING_AMOUNT_CONDITION_ID: i32 = 2547;
|
||||
const REAL_TERRITORY_ACCESS_COST_CONDITION_ID: i32 = 1516;
|
||||
|
||||
const REAL_ORDINARY_CONDITION_METADATA: [RealOrdinaryConditionMetadata; 38] = [
|
||||
const REAL_ORDINARY_CONDITION_METADATA: [RealOrdinaryConditionMetadata; 40] = [
|
||||
RealOrdinaryConditionMetadata {
|
||||
raw_condition_id: 1802,
|
||||
label: "Current Cash",
|
||||
|
|
@ -405,19 +409,33 @@ const REAL_ORDINARY_CONDITION_METADATA: [RealOrdinaryConditionMetadata; 38] = [
|
|||
)),
|
||||
},
|
||||
RealOrdinaryConditionMetadata {
|
||||
raw_condition_id: 2366,
|
||||
raw_condition_id: REAL_INVESTOR_CONFIDENCE_CONDITION_ID,
|
||||
label: "Investor Confidence",
|
||||
kind: RealOrdinaryConditionKind::Numeric(RealOrdinaryConditionMetric::Company(
|
||||
RuntimeCompanyMetric::InvestorConfidence,
|
||||
)),
|
||||
},
|
||||
RealOrdinaryConditionMetadata {
|
||||
raw_condition_id: REAL_CREDIT_RATING_CONDITION_ID,
|
||||
label: "Credit Rating",
|
||||
kind: RealOrdinaryConditionKind::Numeric(RealOrdinaryConditionMetric::Company(
|
||||
RuntimeCompanyMetric::CreditRating,
|
||||
)),
|
||||
},
|
||||
RealOrdinaryConditionMetadata {
|
||||
raw_condition_id: 2368,
|
||||
raw_condition_id: REAL_PRIME_RATE_CONDITION_ID,
|
||||
label: "Prime Rate",
|
||||
kind: RealOrdinaryConditionKind::Numeric(RealOrdinaryConditionMetric::Company(
|
||||
RuntimeCompanyMetric::PrimeRate,
|
||||
)),
|
||||
},
|
||||
RealOrdinaryConditionMetadata {
|
||||
raw_condition_id: REAL_MANAGEMENT_ATTITUDE_CONDITION_ID,
|
||||
label: "Management Attitude",
|
||||
kind: RealOrdinaryConditionKind::Numeric(RealOrdinaryConditionMetric::Company(
|
||||
RuntimeCompanyMetric::ManagementAttitude,
|
||||
)),
|
||||
},
|
||||
RealOrdinaryConditionMetadata {
|
||||
raw_condition_id: REAL_BOOK_VALUE_PER_SHARE_CONDITION_ID,
|
||||
label: "Book Value Per Share",
|
||||
|
|
@ -10559,6 +10577,24 @@ mod tests {
|
|||
.expect("chairman purchasing-power condition metadata should exist");
|
||||
assert_eq!(purchasing_power.label, "Purchasing Power");
|
||||
|
||||
let investor_confidence =
|
||||
real_ordinary_condition_metadata(REAL_INVESTOR_CONFIDENCE_CONDITION_ID)
|
||||
.expect("investor-confidence condition metadata should exist");
|
||||
assert_eq!(investor_confidence.label, "Investor Confidence");
|
||||
|
||||
let credit_rating = real_ordinary_condition_metadata(REAL_CREDIT_RATING_CONDITION_ID)
|
||||
.expect("credit-rating condition metadata should exist");
|
||||
assert_eq!(credit_rating.label, "Credit Rating");
|
||||
|
||||
let prime_rate = real_ordinary_condition_metadata(REAL_PRIME_RATE_CONDITION_ID)
|
||||
.expect("prime-rate condition metadata should exist");
|
||||
assert_eq!(prime_rate.label, "Prime Rate");
|
||||
|
||||
let management_attitude =
|
||||
real_ordinary_condition_metadata(REAL_MANAGEMENT_ATTITUDE_CONDITION_ID)
|
||||
.expect("management-attitude condition metadata should exist");
|
||||
assert_eq!(management_attitude.label, "Management Attitude");
|
||||
|
||||
let book_value = real_ordinary_condition_metadata(REAL_BOOK_VALUE_PER_SHARE_CONDITION_ID)
|
||||
.expect("book value condition metadata should exist");
|
||||
assert_eq!(book_value.label, "Book Value Per Share");
|
||||
|
|
@ -10636,6 +10672,72 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decodes_investor_confidence_condition_to_company_metric() {
|
||||
let row = SmpLoadedPackedEventConditionRowSummary {
|
||||
row_index: 0,
|
||||
raw_condition_id: REAL_INVESTOR_CONFIDENCE_CONDITION_ID,
|
||||
subtype: 4,
|
||||
flag_bytes: {
|
||||
let mut bytes = vec![0; 25];
|
||||
bytes[0..4].copy_from_slice(&37_i32.to_le_bytes());
|
||||
bytes
|
||||
},
|
||||
candidate_name: None,
|
||||
comparator: Some("eq".to_string()),
|
||||
metric: Some("Investor Confidence".to_string()),
|
||||
semantic_family: Some("numeric_threshold".to_string()),
|
||||
semantic_preview: Some("Test Investor Confidence == 37".to_string()),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
requires_candidate_name_binding: false,
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
decode_real_condition_row(&row, None),
|
||||
Some(RuntimeCondition::CompanyNumericThreshold {
|
||||
target: RuntimeCompanyTarget::ConditionTrueCompany,
|
||||
metric: RuntimeCompanyMetric::InvestorConfidence,
|
||||
comparator: RuntimeConditionComparator::Eq,
|
||||
value: 37,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decodes_management_attitude_condition_to_company_metric() {
|
||||
let row = SmpLoadedPackedEventConditionRowSummary {
|
||||
row_index: 0,
|
||||
raw_condition_id: REAL_MANAGEMENT_ATTITUDE_CONDITION_ID,
|
||||
subtype: 4,
|
||||
flag_bytes: {
|
||||
let mut bytes = vec![0; 25];
|
||||
bytes[0..4].copy_from_slice(&58_i32.to_le_bytes());
|
||||
bytes
|
||||
},
|
||||
candidate_name: None,
|
||||
comparator: Some("eq".to_string()),
|
||||
metric: Some("Management Attitude".to_string()),
|
||||
semantic_family: Some("numeric_threshold".to_string()),
|
||||
semantic_preview: Some("Test Management Attitude == 58".to_string()),
|
||||
recovered_cargo_slot: None,
|
||||
recovered_cargo_class: None,
|
||||
requires_candidate_name_binding: false,
|
||||
notes: vec![],
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
decode_real_condition_row(&row, None),
|
||||
Some(RuntimeCondition::CompanyNumericThreshold {
|
||||
target: RuntimeCompanyTarget::ConditionTrueCompany,
|
||||
metric: RuntimeCompanyMetric::ManagementAttitude,
|
||||
comparator: RuntimeConditionComparator::Eq,
|
||||
value: 58,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn looks_up_checked_in_world_flag_descriptor_metadata() {
|
||||
let metadata =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue