Make cargo catalog save-native
This commit is contained in:
parent
0c4a90c16c
commit
c17b9f55f7
24 changed files with 575 additions and 52 deletions
|
|
@ -5,17 +5,17 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::persistence::{load_runtime_snapshot_document, validate_runtime_snapshot_document};
|
||||
use crate::{
|
||||
CalendarPoint, RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind,
|
||||
RuntimeCompanyTarget, RuntimeCondition, RuntimeEffect, RuntimeEventRecord,
|
||||
RuntimeEventRecordTemplate, RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary,
|
||||
RuntimePackedEventCompactControlSummary, RuntimePackedEventConditionRowSummary,
|
||||
RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventNegativeSentinelScopeSummary,
|
||||
RuntimePackedEventRecordSummary, RuntimePackedEventTextBandSummary,
|
||||
RuntimePlayerConditionTestScope, RuntimePlayerTarget, RuntimeSaveProfileState,
|
||||
RuntimeServiceState, RuntimeState, RuntimeTerritoryTarget, RuntimeWorldRestoreState,
|
||||
SmpLoadedPackedEventConditionRowSummary, SmpLoadedPackedEventGroupedEffectRowSummary,
|
||||
SmpLoadedPackedEventNegativeSentinelScopeSummary, SmpLoadedPackedEventRecordSummary,
|
||||
SmpLoadedPackedEventTextBandSummary, SmpLoadedSaveSlice,
|
||||
CalendarPoint, RuntimeCargoCatalogEntry, RuntimeCompanyConditionTestScope,
|
||||
RuntimeCompanyControllerKind, RuntimeCompanyTarget, RuntimeCondition, RuntimeEffect,
|
||||
RuntimeEventRecord, RuntimeEventRecordTemplate, RuntimeLocomotiveCatalogEntry,
|
||||
RuntimePackedEventCollectionSummary, RuntimePackedEventCompactControlSummary,
|
||||
RuntimePackedEventConditionRowSummary, RuntimePackedEventGroupedEffectRowSummary,
|
||||
RuntimePackedEventNegativeSentinelScopeSummary, RuntimePackedEventRecordSummary,
|
||||
RuntimePackedEventTextBandSummary, RuntimePlayerConditionTestScope, RuntimePlayerTarget,
|
||||
RuntimeSaveProfileState, RuntimeServiceState, RuntimeState, RuntimeTerritoryTarget,
|
||||
RuntimeWorldRestoreState, SmpLoadedPackedEventConditionRowSummary,
|
||||
SmpLoadedPackedEventGroupedEffectRowSummary, SmpLoadedPackedEventNegativeSentinelScopeSummary,
|
||||
SmpLoadedPackedEventRecordSummary, SmpLoadedPackedEventTextBandSummary, SmpLoadedSaveSlice,
|
||||
};
|
||||
|
||||
pub const STATE_DUMP_FORMAT_VERSION: u32 = 1;
|
||||
|
|
@ -96,6 +96,7 @@ struct SaveSliceProjection {
|
|||
candidate_availability: BTreeMap<String, u32>,
|
||||
named_locomotive_availability: BTreeMap<String, u32>,
|
||||
locomotive_catalog: Option<Vec<RuntimeLocomotiveCatalogEntry>>,
|
||||
cargo_catalog: Option<Vec<RuntimeCargoCatalogEntry>>,
|
||||
named_locomotive_cost: BTreeMap<String, u32>,
|
||||
cargo_production_overrides: BTreeMap<u32, u32>,
|
||||
special_conditions: BTreeMap<String, u32>,
|
||||
|
|
@ -245,6 +246,7 @@ pub fn project_save_slice_to_runtime_state_import(
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: projection.locomotive_catalog.unwrap_or_default(),
|
||||
cargo_catalog: projection.cargo_catalog.unwrap_or_default(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -309,6 +311,9 @@ pub fn project_save_slice_overlay_to_runtime_state_import(
|
|||
locomotive_catalog: projection
|
||||
.locomotive_catalog
|
||||
.unwrap_or_else(|| base_state.locomotive_catalog.clone()),
|
||||
cargo_catalog: projection
|
||||
.cargo_catalog
|
||||
.unwrap_or_else(|| base_state.cargo_catalog.clone()),
|
||||
territories: base_state.territories.clone(),
|
||||
company_territory_track_piece_counts: base_state
|
||||
.company_territory_track_piece_counts
|
||||
|
|
@ -359,6 +364,10 @@ fn project_save_slice_components(
|
|||
save_slice.locomotive_catalog.is_some()
|
||||
|| save_slice.named_locomotive_availability_table.is_some(),
|
||||
);
|
||||
world_flags.insert(
|
||||
"save_slice.cargo_catalog_present".to_string(),
|
||||
save_slice.cargo_catalog.is_some(),
|
||||
);
|
||||
world_flags.insert(
|
||||
"save_slice.event_runtime_collection_present".to_string(),
|
||||
save_slice.event_runtime_collection.is_some(),
|
||||
|
|
@ -690,6 +699,44 @@ fn project_save_slice_components(
|
|||
} else {
|
||||
None
|
||||
};
|
||||
let cargo_catalog = if let Some(catalog) = &save_slice.cargo_catalog {
|
||||
metadata.insert(
|
||||
"save_slice.cargo_catalog_source_kind".to_string(),
|
||||
catalog.source_kind.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.cargo_catalog_semantic_family".to_string(),
|
||||
catalog.semantic_family.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.cargo_catalog_entry_count".to_string(),
|
||||
catalog.observed_entry_count.to_string(),
|
||||
);
|
||||
if let Some(root_offset) = catalog.root_offset {
|
||||
metadata.insert(
|
||||
"save_slice.cargo_catalog_root_offset".to_string(),
|
||||
root_offset.to_string(),
|
||||
);
|
||||
}
|
||||
Some(
|
||||
catalog
|
||||
.entries
|
||||
.iter()
|
||||
.map(|entry| RuntimeCargoCatalogEntry {
|
||||
slot_id: entry.slot_id,
|
||||
label: entry.label.clone(),
|
||||
supplied_token_stem: entry
|
||||
.supplied_cargo_token_probable_high16_ascii_stem
|
||||
.clone(),
|
||||
demanded_token_stem: entry
|
||||
.demanded_cargo_token_probable_high16_ascii_stem
|
||||
.clone(),
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let named_locomotive_cost = BTreeMap::new();
|
||||
let cargo_production_overrides = BTreeMap::new();
|
||||
|
|
@ -702,8 +749,11 @@ fn project_save_slice_components(
|
|||
.collect();
|
||||
}
|
||||
|
||||
let (packed_event_collection, event_runtime_records) =
|
||||
project_packed_event_collection(save_slice, &packed_event_context)?;
|
||||
let (packed_event_collection, event_runtime_records) = project_packed_event_collection(
|
||||
save_slice,
|
||||
&packed_event_context,
|
||||
cargo_catalog.as_deref().unwrap_or(&[]),
|
||||
)?;
|
||||
if let Some(summary) = &save_slice.event_runtime_collection {
|
||||
metadata.insert(
|
||||
"save_slice.event_runtime_collection_source_kind".to_string(),
|
||||
|
|
@ -741,6 +791,7 @@ fn project_save_slice_components(
|
|||
candidate_availability,
|
||||
named_locomotive_availability,
|
||||
locomotive_catalog,
|
||||
cargo_catalog,
|
||||
named_locomotive_cost,
|
||||
cargo_production_overrides,
|
||||
special_conditions,
|
||||
|
|
@ -750,6 +801,7 @@ fn project_save_slice_components(
|
|||
fn project_packed_event_collection(
|
||||
save_slice: &SmpLoadedSaveSlice,
|
||||
company_context: &ImportRuntimeContext,
|
||||
cargo_catalog: &[RuntimeCargoCatalogEntry],
|
||||
) -> Result<
|
||||
(
|
||||
Option<RuntimePackedEventCollectionSummary>,
|
||||
|
|
@ -780,6 +832,7 @@ fn project_packed_event_collection(
|
|||
runtime_packed_event_record_summary_from_smp(
|
||||
record,
|
||||
company_context,
|
||||
cargo_catalog,
|
||||
imported_record_ids.contains(&record.live_entry_id),
|
||||
)
|
||||
})
|
||||
|
|
@ -810,6 +863,7 @@ fn project_packed_event_collection(
|
|||
fn runtime_packed_event_record_summary_from_smp(
|
||||
record: &SmpLoadedPackedEventRecordSummary,
|
||||
company_context: &ImportRuntimeContext,
|
||||
cargo_catalog: &[RuntimeCargoCatalogEntry],
|
||||
imported: bool,
|
||||
) -> RuntimePackedEventRecordSummary {
|
||||
let lowered_decoded_conditions = lowered_record_decoded_conditions(record, company_context)
|
||||
|
|
@ -840,7 +894,7 @@ fn runtime_packed_event_record_summary_from_smp(
|
|||
standalone_condition_rows: record
|
||||
.standalone_condition_rows
|
||||
.iter()
|
||||
.map(runtime_packed_event_condition_row_summary_from_smp)
|
||||
.map(|row| runtime_packed_event_condition_row_summary_from_smp(row, cargo_catalog))
|
||||
.collect(),
|
||||
negative_sentinel_scope: record
|
||||
.negative_sentinel_scope
|
||||
|
|
@ -850,7 +904,7 @@ fn runtime_packed_event_record_summary_from_smp(
|
|||
grouped_effect_rows: record
|
||||
.grouped_effect_rows
|
||||
.iter()
|
||||
.map(runtime_packed_event_grouped_effect_row_summary_from_smp)
|
||||
.map(|row| runtime_packed_event_grouped_effect_row_summary_from_smp(row, cargo_catalog))
|
||||
.collect(),
|
||||
grouped_company_targets: classify_real_grouped_company_targets(record),
|
||||
decoded_conditions: lowered_decoded_conditions,
|
||||
|
|
@ -906,7 +960,11 @@ fn runtime_packed_event_text_band_summary_from_smp(
|
|||
|
||||
fn runtime_packed_event_condition_row_summary_from_smp(
|
||||
row: &crate::SmpLoadedPackedEventConditionRowSummary,
|
||||
cargo_catalog: &[RuntimeCargoCatalogEntry],
|
||||
) -> RuntimePackedEventConditionRowSummary {
|
||||
let cargo_entry = row
|
||||
.recovered_cargo_slot
|
||||
.and_then(|slot| cargo_catalog.iter().find(|entry| entry.slot_id == slot));
|
||||
RuntimePackedEventConditionRowSummary {
|
||||
row_index: row.row_index,
|
||||
raw_condition_id: row.raw_condition_id,
|
||||
|
|
@ -918,13 +976,26 @@ fn runtime_packed_event_condition_row_summary_from_smp(
|
|||
semantic_family: row.semantic_family.clone(),
|
||||
semantic_preview: row.semantic_preview.clone(),
|
||||
requires_candidate_name_binding: row.requires_candidate_name_binding,
|
||||
recovered_cargo_slot: row.recovered_cargo_slot,
|
||||
recovered_cargo_class: row.recovered_cargo_class.clone(),
|
||||
recovered_cargo_label: cargo_entry
|
||||
.map(|entry| entry.label.clone())
|
||||
.or_else(|| row.recovered_cargo_slot.map(default_cargo_slot_label)),
|
||||
recovered_cargo_supplied_token_stem: cargo_entry
|
||||
.and_then(|entry| entry.supplied_token_stem.clone()),
|
||||
recovered_cargo_demanded_token_stem: cargo_entry
|
||||
.and_then(|entry| entry.demanded_token_stem.clone()),
|
||||
notes: row.notes.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn runtime_packed_event_grouped_effect_row_summary_from_smp(
|
||||
row: &crate::SmpLoadedPackedEventGroupedEffectRowSummary,
|
||||
cargo_catalog: &[RuntimeCargoCatalogEntry],
|
||||
) -> RuntimePackedEventGroupedEffectRowSummary {
|
||||
let cargo_entry = row
|
||||
.recovered_cargo_slot
|
||||
.and_then(|slot| cargo_catalog.iter().find(|entry| entry.slot_id == slot));
|
||||
RuntimePackedEventGroupedEffectRowSummary {
|
||||
group_index: row.group_index,
|
||||
row_index: row.row_index,
|
||||
|
|
@ -943,12 +1014,25 @@ fn runtime_packed_event_grouped_effect_row_summary_from_smp(
|
|||
row_shape: row.row_shape.clone(),
|
||||
semantic_family: row.semantic_family.clone(),
|
||||
semantic_preview: row.semantic_preview.clone(),
|
||||
recovered_cargo_slot: row.recovered_cargo_slot,
|
||||
recovered_cargo_class: row.recovered_cargo_class.clone(),
|
||||
recovered_cargo_label: cargo_entry
|
||||
.map(|entry| entry.label.clone())
|
||||
.or_else(|| row.recovered_cargo_slot.map(default_cargo_slot_label)),
|
||||
recovered_cargo_supplied_token_stem: cargo_entry
|
||||
.and_then(|entry| entry.supplied_token_stem.clone()),
|
||||
recovered_cargo_demanded_token_stem: cargo_entry
|
||||
.and_then(|entry| entry.demanded_token_stem.clone()),
|
||||
recovered_locomotive_id: row.recovered_locomotive_id,
|
||||
locomotive_name: row.locomotive_name.clone(),
|
||||
notes: row.notes.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn default_cargo_slot_label(slot: u32) -> String {
|
||||
format!("Cargo Production Slot {slot}")
|
||||
}
|
||||
|
||||
fn smp_packed_record_to_runtime_event_record(
|
||||
record: &SmpLoadedPackedEventRecordSummary,
|
||||
company_context: &ImportRuntimeContext,
|
||||
|
|
@ -2251,6 +2335,17 @@ fn determine_packed_event_import_outcome(
|
|||
{
|
||||
return "blocked_retire_train_variant".to_string();
|
||||
}
|
||||
if record
|
||||
.standalone_condition_rows
|
||||
.iter()
|
||||
.any(|row| row.raw_condition_id >= 0)
|
||||
{
|
||||
if record_has_world_state_condition_rows(record) {
|
||||
return "blocked_unmapped_world_condition".to_string();
|
||||
} else {
|
||||
return "blocked_unmapped_ordinary_condition".to_string();
|
||||
}
|
||||
}
|
||||
if record
|
||||
.grouped_effect_rows
|
||||
.iter()
|
||||
|
|
@ -2258,19 +2353,7 @@ fn determine_packed_event_import_outcome(
|
|||
{
|
||||
return "blocked_unmapped_world_descriptor".to_string();
|
||||
}
|
||||
return if record
|
||||
.standalone_condition_rows
|
||||
.iter()
|
||||
.any(|row| row.raw_condition_id >= 0)
|
||||
{
|
||||
if record_has_world_state_condition_rows(record) {
|
||||
"blocked_unmapped_world_condition".to_string()
|
||||
} else {
|
||||
"blocked_unmapped_ordinary_condition".to_string()
|
||||
}
|
||||
} else {
|
||||
"blocked_unmapped_real_descriptor".to_string()
|
||||
};
|
||||
return "blocked_unmapped_real_descriptor".to_string();
|
||||
}
|
||||
if let Some(blocker) = packed_record_condition_scope_import_blocker(record, company_context)
|
||||
{
|
||||
|
|
@ -2952,6 +3035,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -3717,6 +3801,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: None,
|
||||
notes: vec![],
|
||||
|
|
@ -3757,6 +3842,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: None,
|
||||
notes: vec![],
|
||||
|
|
@ -3871,6 +3957,7 @@ mod tests {
|
|||
},
|
||||
),
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: Some(crate::SmpLoadedSpecialConditionsTable {
|
||||
source_kind: "save-fixed-special-conditions-range".to_string(),
|
||||
table_offset: 0x0d64,
|
||||
|
|
@ -4196,6 +4283,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -4311,6 +4399,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -4404,6 +4493,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -4515,6 +4605,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -4599,6 +4690,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -4733,6 +4825,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -4975,6 +5068,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5052,6 +5146,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5153,6 +5248,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5227,6 +5323,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5328,6 +5425,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5405,6 +5503,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: Some(save_named_locomotive_table(112)),
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5522,6 +5621,7 @@ mod tests {
|
|||
name: "Locomotive 112".to_string(),
|
||||
},
|
||||
],
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -5548,6 +5648,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5650,6 +5751,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5726,6 +5828,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5802,6 +5905,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: Some(save_named_locomotive_table(112)),
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -5912,6 +6016,7 @@ mod tests {
|
|||
name: "Locomotive 101".to_string(),
|
||||
},
|
||||
],
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -5938,6 +6043,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6033,6 +6139,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6107,6 +6214,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6191,6 +6299,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6294,6 +6403,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -6317,6 +6427,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6464,6 +6575,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6568,6 +6680,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6653,6 +6766,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6759,6 +6873,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6865,6 +6980,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -6961,6 +7077,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7053,6 +7170,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7153,6 +7271,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7244,6 +7363,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7317,6 +7437,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7395,6 +7516,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7478,6 +7600,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7561,6 +7684,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7660,6 +7784,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7750,6 +7875,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7866,6 +7992,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -7995,6 +8122,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -8292,6 +8420,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -8402,6 +8531,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -8575,6 +8705,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -8668,6 +8799,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -8757,6 +8889,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -8911,6 +9044,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -9054,6 +9188,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -9144,6 +9279,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -9261,6 +9397,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -9366,6 +9503,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -9474,6 +9612,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -9512,6 +9651,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
@ -9656,6 +9796,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -9687,6 +9828,7 @@ mod tests {
|
|||
candidate_availability_table: None,
|
||||
named_locomotive_availability_table: None,
|
||||
locomotive_catalog: None,
|
||||
cargo_catalog: None,
|
||||
special_conditions_table: None,
|
||||
event_runtime_collection: Some(crate::SmpLoadedEventRuntimeCollectionSummary {
|
||||
source_kind: "packed-event-runtime-collection".to_string(),
|
||||
|
|
|
|||
|
|
@ -35,29 +35,30 @@ pub use pk4::{
|
|||
extract_pk4_entry_bytes, extract_pk4_entry_file, inspect_pk4_bytes, inspect_pk4_file,
|
||||
};
|
||||
pub use runtime::{
|
||||
RuntimeCompany, RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind,
|
||||
RuntimeCompanyMetric, RuntimeCompanyTarget, RuntimeCompanyTerritoryAccess,
|
||||
RuntimeCompanyTerritoryTrackPieceCount, RuntimeCondition, RuntimeConditionComparator,
|
||||
RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate, RuntimeLocomotiveCatalogEntry,
|
||||
RuntimePackedEventCollectionSummary, RuntimePackedEventCompactControlSummary,
|
||||
RuntimePackedEventConditionRowSummary, RuntimePackedEventGroupedEffectRowSummary,
|
||||
RuntimePackedEventNegativeSentinelScopeSummary, RuntimePackedEventRecordSummary,
|
||||
RuntimePackedEventTextBandSummary, RuntimePlayer, RuntimePlayerConditionTestScope,
|
||||
RuntimePlayerTarget, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState,
|
||||
RuntimeTerritory, RuntimeTerritoryMetric, RuntimeTerritoryTarget, RuntimeTrackMetric,
|
||||
RuntimeTrackPieceCounts, RuntimeTrain, RuntimeWorldRestoreState,
|
||||
RuntimeCargoCatalogEntry, RuntimeCompany, RuntimeCompanyConditionTestScope,
|
||||
RuntimeCompanyControllerKind, RuntimeCompanyMetric, RuntimeCompanyTarget,
|
||||
RuntimeCompanyTerritoryAccess, RuntimeCompanyTerritoryTrackPieceCount, RuntimeCondition,
|
||||
RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate,
|
||||
RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary,
|
||||
RuntimePackedEventCompactControlSummary, RuntimePackedEventConditionRowSummary,
|
||||
RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventNegativeSentinelScopeSummary,
|
||||
RuntimePackedEventRecordSummary, RuntimePackedEventTextBandSummary, RuntimePlayer,
|
||||
RuntimePlayerConditionTestScope, RuntimePlayerTarget, RuntimeSaveProfileState,
|
||||
RuntimeServiceState, RuntimeState, RuntimeTerritory, RuntimeTerritoryMetric,
|
||||
RuntimeTerritoryTarget, RuntimeTrackMetric, RuntimeTrackPieceCounts, RuntimeTrain,
|
||||
RuntimeWorldRestoreState,
|
||||
};
|
||||
pub use smp::{
|
||||
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,
|
||||
SmpAlignedRuntimeRuleBandProbe, SmpAsciiPreview, SmpClassicPackedProfileBlock,
|
||||
SmpClassicRehydrateProfileProbe, SmpContainerProfile, SmpEarlyContentProbe,
|
||||
SmpHeaderVariantProbe, SmpInspectionReport, SmpKnownTagHit,
|
||||
SmpLoadedCandidateAvailabilityTable, SmpLoadedEventRuntimeCollectionSummary,
|
||||
SmpLoadedNamedLocomotiveAvailabilityTable, SmpLoadedPackedEventCompactControlSummary,
|
||||
SmpLoadedPackedEventConditionRowSummary, SmpLoadedPackedEventGroupedEffectRowSummary,
|
||||
SmpLoadedPackedEventNegativeSentinelScopeSummary, SmpLoadedPackedEventRecordSummary,
|
||||
SmpLoadedPackedEventTextBandSummary, SmpLoadedProfile, SmpLoadedSaveSlice,
|
||||
SmpLoadedSpecialConditionsTable, SmpLocomotivePolicyFieldObservation,
|
||||
SmpLoadedCandidateAvailabilityTable, SmpLoadedCargoCatalog, SmpLoadedCargoCatalogEntry,
|
||||
SmpLoadedEventRuntimeCollectionSummary, SmpLoadedNamedLocomotiveAvailabilityTable,
|
||||
SmpLoadedPackedEventCompactControlSummary, SmpLoadedPackedEventConditionRowSummary,
|
||||
SmpLoadedPackedEventGroupedEffectRowSummary, SmpLoadedPackedEventNegativeSentinelScopeSummary,
|
||||
SmpLoadedPackedEventRecordSummary, SmpLoadedPackedEventTextBandSummary, SmpLoadedProfile,
|
||||
SmpLoadedSaveSlice, SmpLoadedSpecialConditionsTable, SmpLocomotivePolicyFieldObservation,
|
||||
SmpLocomotivePolicyFloatAlignmentCandidate, SmpLocomotivePolicyNeighborhoodProbe,
|
||||
SmpPackedProfileWordLane, SmpPostSpecialConditionsScalarLane,
|
||||
SmpPostSpecialConditionsScalarProbe, SmpPostTextFieldNeighborhoodProbe,
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
|
|||
|
|
@ -113,6 +113,16 @@ pub struct RuntimeLocomotiveCatalogEntry {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct RuntimeCargoCatalogEntry {
|
||||
pub slot_id: u32,
|
||||
pub label: String,
|
||||
#[serde(default)]
|
||||
pub supplied_token_stem: Option<String>,
|
||||
#[serde(default)]
|
||||
pub demanded_token_stem: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum RuntimeCompanyTarget {
|
||||
|
|
@ -533,6 +543,16 @@ pub struct RuntimePackedEventConditionRowSummary {
|
|||
#[serde(default)]
|
||||
pub requires_candidate_name_binding: bool,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_slot: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_class: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_label: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_supplied_token_stem: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_demanded_token_stem: Option<String>,
|
||||
#[serde(default)]
|
||||
pub notes: Vec<String>,
|
||||
}
|
||||
|
||||
|
|
@ -561,6 +581,16 @@ pub struct RuntimePackedEventGroupedEffectRowSummary {
|
|||
#[serde(default)]
|
||||
pub semantic_preview: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_slot: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_class: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_label: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_supplied_token_stem: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_cargo_demanded_token_stem: Option<String>,
|
||||
#[serde(default)]
|
||||
pub recovered_locomotive_id: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub locomotive_name: Option<String>,
|
||||
|
|
@ -684,6 +714,8 @@ pub struct RuntimeState {
|
|||
#[serde(default)]
|
||||
pub locomotive_catalog: Vec<RuntimeLocomotiveCatalogEntry>,
|
||||
#[serde(default)]
|
||||
pub cargo_catalog: Vec<RuntimeCargoCatalogEntry>,
|
||||
#[serde(default)]
|
||||
pub territories: Vec<RuntimeTerritory>,
|
||||
#[serde(default)]
|
||||
pub company_territory_track_piece_counts: Vec<RuntimeCompanyTerritoryTrackPieceCount>,
|
||||
|
|
@ -837,6 +869,28 @@ impl RuntimeState {
|
|||
));
|
||||
}
|
||||
}
|
||||
let mut seen_cargo_slots = BTreeSet::new();
|
||||
let mut seen_cargo_labels = BTreeSet::new();
|
||||
for entry in &self.cargo_catalog {
|
||||
if !(1..=11).contains(&entry.slot_id) {
|
||||
return Err(format!(
|
||||
"cargo_catalog entry has out-of-range slot_id {}",
|
||||
entry.slot_id
|
||||
));
|
||||
}
|
||||
if !seen_cargo_slots.insert(entry.slot_id) {
|
||||
return Err(format!("duplicate cargo_catalog.slot_id {}", entry.slot_id));
|
||||
}
|
||||
if entry.label.trim().is_empty() {
|
||||
return Err(format!(
|
||||
"cargo_catalog entry {} has an empty label",
|
||||
entry.slot_id
|
||||
));
|
||||
}
|
||||
if !seen_cargo_labels.insert(entry.label.clone()) {
|
||||
return Err(format!("duplicate cargo_catalog.label {:?}", entry.label));
|
||||
}
|
||||
}
|
||||
for entry in &self.company_territory_track_piece_counts {
|
||||
if !seen_company_ids.contains(&entry.company_id) {
|
||||
return Err(format!(
|
||||
|
|
@ -1550,6 +1604,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1610,6 +1665,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1655,6 +1711,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1713,6 +1770,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1771,6 +1829,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1880,6 +1939,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1925,6 +1985,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1987,6 +2048,7 @@ mod tests {
|
|||
},
|
||||
],
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -2039,6 +2101,7 @@ mod tests {
|
|||
retired: false,
|
||||
}],
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -2091,6 +2154,7 @@ mod tests {
|
|||
retired: false,
|
||||
}],
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: vec![RuntimeTerritory {
|
||||
territory_id: 1,
|
||||
name: Some("Appalachia".to_string()),
|
||||
|
|
@ -2147,6 +2211,7 @@ mod tests {
|
|||
retired: true,
|
||||
}],
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -2192,6 +2257,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: vec![RuntimeTerritory {
|
||||
territory_id: 7,
|
||||
name: Some("Appalachia".to_string()),
|
||||
|
|
@ -2250,6 +2316,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: vec![RuntimeTerritory {
|
||||
territory_id: 7,
|
||||
name: Some("Appalachia".to_string()),
|
||||
|
|
@ -2302,6 +2369,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: vec![RuntimeTerritory {
|
||||
territory_id: 7,
|
||||
name: Some("Appalachia".to_string()),
|
||||
|
|
|
|||
|
|
@ -1625,6 +1625,33 @@ pub struct SmpLoadedLocomotiveCatalog {
|
|||
pub entries: Vec<SmpLoadedLocomotiveCatalogEntry>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SmpLoadedCargoCatalogEntry {
|
||||
pub slot_id: u32,
|
||||
pub label: String,
|
||||
pub book_index: usize,
|
||||
pub max_annual_production_word: u32,
|
||||
pub mode_word: u32,
|
||||
pub runtime_import_branch_kind: String,
|
||||
pub annual_amount_word: u32,
|
||||
pub supplied_cargo_token_word: u32,
|
||||
#[serde(default)]
|
||||
pub supplied_cargo_token_probable_high16_ascii_stem: Option<String>,
|
||||
pub demanded_cargo_token_word: u32,
|
||||
#[serde(default)]
|
||||
pub demanded_cargo_token_probable_high16_ascii_stem: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SmpLoadedCargoCatalog {
|
||||
pub source_kind: String,
|
||||
pub semantic_family: String,
|
||||
#[serde(default)]
|
||||
pub root_offset: Option<usize>,
|
||||
pub observed_entry_count: usize,
|
||||
pub entries: Vec<SmpLoadedCargoCatalogEntry>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SmpLoadedSpecialConditionsTable {
|
||||
pub source_kind: String,
|
||||
|
|
@ -1808,6 +1835,8 @@ pub struct SmpLoadedSaveSlice {
|
|||
pub named_locomotive_availability_table: Option<SmpLoadedNamedLocomotiveAvailabilityTable>,
|
||||
#[serde(default)]
|
||||
pub locomotive_catalog: Option<SmpLoadedLocomotiveCatalog>,
|
||||
#[serde(default)]
|
||||
pub cargo_catalog: Option<SmpLoadedCargoCatalog>,
|
||||
pub special_conditions_table: Option<SmpLoadedSpecialConditionsTable>,
|
||||
pub event_runtime_collection: Option<SmpLoadedEventRuntimeCollectionSummary>,
|
||||
pub notes: Vec<String>,
|
||||
|
|
@ -1972,6 +2001,10 @@ pub fn load_save_slice_from_report(
|
|||
let locomotive_catalog = named_locomotive_availability_table
|
||||
.as_ref()
|
||||
.and_then(derive_locomotive_catalog_from_named_availability_table);
|
||||
let cargo_catalog = report
|
||||
.recipe_book_summary_probe
|
||||
.as_ref()
|
||||
.and_then(derive_cargo_catalog_from_recipe_book_probe);
|
||||
let special_conditions_table =
|
||||
report
|
||||
.special_conditions_probe
|
||||
|
|
@ -1996,6 +2029,7 @@ pub fn load_save_slice_from_report(
|
|||
candidate_availability_table,
|
||||
named_locomotive_availability_table,
|
||||
locomotive_catalog,
|
||||
cargo_catalog,
|
||||
special_conditions_table,
|
||||
event_runtime_collection: report.event_runtime_collection_summary.clone(),
|
||||
notes: summary.notes.clone(),
|
||||
|
|
@ -2028,6 +2062,57 @@ fn derive_locomotive_catalog_from_named_availability_table(
|
|||
})
|
||||
}
|
||||
|
||||
fn derive_cargo_catalog_from_recipe_book_probe(
|
||||
probe: &SmpRecipeBookSummaryProbe,
|
||||
) -> Option<SmpLoadedCargoCatalog> {
|
||||
if probe.books.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let entries = probe
|
||||
.books
|
||||
.iter()
|
||||
.filter(|book| book.book_index < 11)
|
||||
.filter_map(|book| {
|
||||
let line = book
|
||||
.lines
|
||||
.iter()
|
||||
.find(|line| line.imports_to_runtime_descriptor)
|
||||
.or_else(|| book.lines.first())?;
|
||||
let slot_id = (book.book_index + 1) as u32;
|
||||
Some(SmpLoadedCargoCatalogEntry {
|
||||
slot_id,
|
||||
label: format!("Cargo Production Slot {slot_id}"),
|
||||
book_index: book.book_index,
|
||||
max_annual_production_word: book.max_annual_production_word,
|
||||
mode_word: line.mode_word,
|
||||
runtime_import_branch_kind: line.runtime_import_branch_kind.clone(),
|
||||
annual_amount_word: line.annual_amount_word,
|
||||
supplied_cargo_token_word: line.supplied_cargo_token_word,
|
||||
supplied_cargo_token_probable_high16_ascii_stem: line
|
||||
.supplied_cargo_token_probable_high16_ascii_stem
|
||||
.clone(),
|
||||
demanded_cargo_token_word: line.demanded_cargo_token_word,
|
||||
demanded_cargo_token_probable_high16_ascii_stem: line
|
||||
.demanded_cargo_token_probable_high16_ascii_stem
|
||||
.clone(),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if entries.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(SmpLoadedCargoCatalog {
|
||||
source_kind: format!("{}-slot-catalog", probe.source_kind),
|
||||
semantic_family: "scenario-save-derived-cargo-catalog".to_string(),
|
||||
root_offset: Some(probe.root_offset),
|
||||
observed_entry_count: entries.len(),
|
||||
entries,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_event_runtime_collection_summary(
|
||||
bytes: &[u8],
|
||||
container_profile: Option<&SmpContainerProfile>,
|
||||
|
|
|
|||
|
|
@ -1249,6 +1249,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ pub struct RuntimeSummary {
|
|||
pub active_train_count: usize,
|
||||
pub retired_train_count: usize,
|
||||
pub locomotive_catalog_count: usize,
|
||||
pub cargo_catalog_count: usize,
|
||||
pub territory_count: usize,
|
||||
pub company_territory_track_count: usize,
|
||||
pub packed_event_collection_present: bool,
|
||||
|
|
@ -172,6 +173,7 @@ impl RuntimeSummary {
|
|||
active_train_count: state.trains.iter().filter(|train| train.active).count(),
|
||||
retired_train_count: state.trains.iter().filter(|train| train.retired).count(),
|
||||
locomotive_catalog_count: state.locomotive_catalog.len(),
|
||||
cargo_catalog_count: state.cargo_catalog.len(),
|
||||
territory_count: state.territories.len(),
|
||||
company_territory_track_count: state.company_territory_track_piece_counts.len(),
|
||||
packed_event_collection_present: state.packed_event_collection.is_some(),
|
||||
|
|
@ -675,6 +677,7 @@ mod tests {
|
|||
name: "Locomotive 112".to_string(),
|
||||
},
|
||||
],
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -917,6 +920,7 @@ mod tests {
|
|||
name: "Locomotive 112".to_string(),
|
||||
},
|
||||
],
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -963,6 +967,7 @@ mod tests {
|
|||
name: "Locomotive 112".to_string(),
|
||||
},
|
||||
],
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1006,6 +1011,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1049,6 +1055,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1087,6 +1094,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
@ -1194,6 +1202,7 @@ mod tests {
|
|||
selected_player_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue