Rehost periodic route preference service seam

This commit is contained in:
Jan Petykiewicz 2026-04-18 07:42:59 -07:00
commit f7fde709f7
9 changed files with 578 additions and 49 deletions

View file

@ -855,6 +855,34 @@ fn project_save_slice_components(
.as_ref()
.and_then(|state| state.linked_site_removal_follow_on_gate_raw_u8)
.map(|raw| raw != 0),
auto_show_grade_during_track_lay_raw_u8: save_slice
.world_locomotive_policy_state
.as_ref()
.and_then(|state| state.auto_show_grade_during_track_lay_raw_u8),
starting_building_density_level_raw_u8: save_slice
.world_locomotive_policy_state
.as_ref()
.and_then(|state| state.starting_building_density_level_raw_u8),
post_text_building_density_growth_raw_u8: save_slice
.world_locomotive_policy_state
.as_ref()
.and_then(|state| state.building_density_growth_raw_u8),
leftover_simulation_time_accumulator_raw_u32: save_slice
.world_locomotive_policy_state
.as_ref()
.and_then(|state| state.leftover_simulation_time_accumulator_raw_u32),
leftover_simulation_time_accumulator_value_f32_text: save_slice
.world_locomotive_policy_state
.as_ref()
.and_then(|state| {
state
.leftover_simulation_time_accumulator_value_f32_text
.clone()
}),
selected_year_lane_snapshot_raw_u8: save_slice
.world_locomotive_policy_state
.as_ref()
.and_then(|state| state.selected_year_lane_snapshot_raw_u8),
all_steam_locomotives_available_raw_u8: save_slice
.world_locomotive_policy_state
.as_ref()
@ -6191,6 +6219,17 @@ mod tests {
selected_year_gap_scalar_value_f32_text: Some("0.333333".to_string()),
linked_site_removal_follow_on_gate_raw_u8: Some(1),
linked_site_removal_follow_on_gate_raw_hex: Some("0x01".to_string()),
auto_show_grade_during_track_lay_raw_u8: Some(2),
auto_show_grade_during_track_lay_raw_hex: Some("0x02".to_string()),
starting_building_density_level_raw_u8: Some(3),
starting_building_density_level_raw_hex: Some("0x03".to_string()),
building_density_growth_raw_u8: Some(1),
building_density_growth_raw_hex: Some("0x01".to_string()),
leftover_simulation_time_accumulator_raw_u32: Some(0x3f000000),
leftover_simulation_time_accumulator_raw_hex: Some("0x3f000000".to_string()),
leftover_simulation_time_accumulator_value_f32_text: Some("0.500000".to_string()),
selected_year_lane_snapshot_raw_u8: Some(7),
selected_year_lane_snapshot_raw_hex: Some("0x07".to_string()),
all_steam_locomotives_available_raw_u8: Some(1),
all_steam_locomotives_available_raw_hex: Some("0x01".to_string()),
all_diesel_locomotives_available_raw_u8: Some(0),
@ -6368,6 +6407,49 @@ mod tests {
.absolute_counter_reconstructible_from_save,
Some(true)
);
assert_eq!(
import
.state
.world_restore
.auto_show_grade_during_track_lay_raw_u8,
Some(2)
);
assert_eq!(
import
.state
.world_restore
.starting_building_density_level_raw_u8,
Some(3)
);
assert_eq!(
import
.state
.world_restore
.post_text_building_density_growth_raw_u8,
Some(1)
);
assert_eq!(
import
.state
.world_restore
.leftover_simulation_time_accumulator_raw_u32,
Some(0x3f000000)
);
assert_eq!(
import
.state
.world_restore
.leftover_simulation_time_accumulator_value_f32_text
.as_deref(),
Some("0.500000")
);
assert_eq!(
import
.state
.world_restore
.selected_year_lane_snapshot_raw_u8,
Some(7)
);
assert_eq!(
import.state.world_restore.packed_year_word_raw_u16,
Some(0x0201)

View file

@ -58,18 +58,19 @@ pub use runtime::{
RuntimeCompanyAnnualFinanceState, RuntimeCompanyAnnualStockIssueState,
RuntimeCompanyAnnualStockRepurchaseState, RuntimeCompanyBondSlot,
RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind, RuntimeCompanyMarketMetric,
RuntimeCompanyMarketState, RuntimeCompanyMetric, RuntimeCompanyPeriodicSideLatchState,
RuntimeCompanyStatBandCandidate, RuntimeCompanyStatSelector, 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,
RuntimeWorldFinanceNeighborhoodCandidate, RuntimeWorldIssueState, RuntimeWorldRestoreState,
RuntimeCompanyMarketState, RuntimeCompanyMetric, RuntimeCompanyPeriodicServiceState,
RuntimeCompanyPeriodicSideLatchState, RuntimeCompanyStatBandCandidate,
RuntimeCompanyStatSelector, 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, RuntimeWorldFinanceNeighborhoodCandidate,
RuntimeWorldIssueState, RuntimeWorldRestoreState,
runtime_annual_bond_principal_flow_relation_label,
runtime_annual_finance_news_family_candidate_label, runtime_company_annual_bond_policy_state,
runtime_company_annual_creditor_pressure_state, runtime_company_annual_deep_distress_state,
@ -80,14 +81,15 @@ pub use runtime::{
runtime_company_assigned_share_pool, runtime_company_average_live_bond_coupon,
runtime_company_book_value_per_share, runtime_company_credit_rating,
runtime_company_investor_confidence, runtime_company_management_attitude,
runtime_company_market_value, runtime_company_prime_rate,
runtime_company_recent_per_share_subscore, runtime_company_stat_value,
runtime_company_stat_value_f64, runtime_company_unassigned_share_pool,
runtime_world_annual_finance_mode_active, runtime_world_bankruptcy_allowed,
runtime_world_bond_issue_and_repayment_allowed, runtime_world_building_density_growth_setting,
runtime_world_dividend_adjustment_allowed, runtime_world_issue_opinion_multiplier,
runtime_world_issue_opinion_term_sum_raw, runtime_world_issue_state,
runtime_world_prime_rate_baseline, runtime_world_stock_issue_and_buyback_allowed,
runtime_company_market_value, runtime_company_periodic_service_state,
runtime_company_prime_rate, runtime_company_recent_per_share_subscore,
runtime_company_stat_value, runtime_company_stat_value_f64,
runtime_company_unassigned_share_pool, runtime_world_annual_finance_mode_active,
runtime_world_bankruptcy_allowed, runtime_world_bond_issue_and_repayment_allowed,
runtime_world_building_density_growth_setting, runtime_world_dividend_adjustment_allowed,
runtime_world_issue_opinion_multiplier, runtime_world_issue_opinion_term_sum_raw,
runtime_world_issue_state, runtime_world_prime_rate_baseline,
runtime_world_stock_issue_and_buyback_allowed,
};
pub use smp::{
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,

View file

@ -194,6 +194,21 @@ pub struct RuntimeCompanyPeriodicSideLatchState {
pub linked_transit_latch: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeCompanyPeriodicServiceState {
pub company_id: u32,
#[serde(default)]
pub preferred_locomotive_engine_type_raw_u8: Option<u8>,
pub city_connection_latch: bool,
pub linked_transit_latch: bool,
#[serde(default)]
pub base_route_preference_raw_u8: Option<u8>,
#[serde(default)]
pub effective_route_preference_raw_u8: Option<u8>,
pub electric_route_preference_override_active: bool,
pub effective_route_quality_multiplier_basis_points: i64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeCompanyAnnualCreditorPressureState {
pub company_id: u32,
@ -1377,6 +1392,18 @@ pub struct RuntimeWorldRestoreState {
#[serde(default)]
pub linked_site_removal_follow_on_gate_enabled: Option<bool>,
#[serde(default)]
pub auto_show_grade_during_track_lay_raw_u8: Option<u8>,
#[serde(default)]
pub starting_building_density_level_raw_u8: Option<u8>,
#[serde(default)]
pub post_text_building_density_growth_raw_u8: Option<u8>,
#[serde(default)]
pub leftover_simulation_time_accumulator_raw_u32: Option<u32>,
#[serde(default)]
pub leftover_simulation_time_accumulator_value_f32_text: Option<String>,
#[serde(default)]
pub selected_year_lane_snapshot_raw_u8: Option<u8>,
#[serde(default)]
pub all_steam_locomotives_available_raw_u8: Option<u8>,
#[serde(default)]
pub all_steam_locomotives_available_enabled: Option<bool>,
@ -4523,10 +4550,7 @@ pub fn runtime_company_annual_finance_state(
company_id: u32,
) -> Option<RuntimeCompanyAnnualFinanceState> {
let market_state = state.service_state.company_market_state.get(&company_id)?;
let periodic_side_latch_state = state
.service_state
.company_periodic_side_latch_state
.get(&company_id);
let periodic_service_state = runtime_company_periodic_service_state(state, company_id);
let assigned_share_pool = runtime_company_assigned_share_pool(state, company_id)?;
let unassigned_share_pool = runtime_company_unassigned_share_pool(state, company_id)?;
let years_since_founding =
@ -4601,14 +4625,61 @@ pub fn runtime_company_annual_finance_state(
current_issue_calendar_word_2: market_state.current_issue_calendar_word_2,
prior_issue_calendar_word: market_state.prior_issue_calendar_word,
prior_issue_calendar_word_2: market_state.prior_issue_calendar_word_2,
preferred_locomotive_engine_type_raw_u8: periodic_side_latch_state
.and_then(|latch_state| latch_state.preferred_locomotive_engine_type_raw_u8),
preferred_locomotive_engine_type_raw_u8: periodic_service_state
.as_ref()
.and_then(|service_state| service_state.preferred_locomotive_engine_type_raw_u8),
city_connection_latch: periodic_service_state
.as_ref()
.map(|service_state| service_state.city_connection_latch)
.unwrap_or(market_state.city_connection_latch),
linked_transit_latch: periodic_service_state
.as_ref()
.map(|service_state| service_state.linked_transit_latch)
.unwrap_or(market_state.linked_transit_latch),
})
}
pub fn runtime_company_periodic_service_state(
state: &RuntimeState,
company_id: u32,
) -> Option<RuntimeCompanyPeriodicServiceState> {
const DEFAULT_ROUTE_QUALITY_MULTIPLIER_BASIS_POINTS: i64 = 140;
const ELECTRIC_ROUTE_QUALITY_MULTIPLIER_BASIS_POINTS: i64 = 180;
const ELECTRIC_ENGINE_TYPE_RAW_U8: u8 = 2;
let market_state = state.service_state.company_market_state.get(&company_id)?;
let periodic_side_latch_state = state
.service_state
.company_periodic_side_latch_state
.get(&company_id);
let preferred_locomotive_engine_type_raw_u8 = periodic_side_latch_state
.and_then(|latch_state| latch_state.preferred_locomotive_engine_type_raw_u8);
let base_route_preference_raw_u8 = state.world_restore.auto_show_grade_during_track_lay_raw_u8;
let electric_route_preference_override_active =
preferred_locomotive_engine_type_raw_u8 == Some(ELECTRIC_ENGINE_TYPE_RAW_U8);
let effective_route_preference_raw_u8 = if electric_route_preference_override_active {
Some(ELECTRIC_ENGINE_TYPE_RAW_U8)
} else {
base_route_preference_raw_u8
};
Some(RuntimeCompanyPeriodicServiceState {
company_id,
preferred_locomotive_engine_type_raw_u8,
city_connection_latch: periodic_side_latch_state
.map(|latch_state| latch_state.city_connection_latch)
.unwrap_or(market_state.city_connection_latch),
linked_transit_latch: periodic_side_latch_state
.map(|latch_state| latch_state.linked_transit_latch)
.unwrap_or(market_state.linked_transit_latch),
base_route_preference_raw_u8,
effective_route_preference_raw_u8,
electric_route_preference_override_active,
effective_route_quality_multiplier_basis_points:
if electric_route_preference_override_active {
ELECTRIC_ROUTE_QUALITY_MULTIPLIER_BASIS_POINTS
} else {
DEFAULT_ROUTE_QUALITY_MULTIPLIER_BASIS_POINTS
},
})
}
@ -5259,6 +5330,12 @@ mod tests {
territory_access_cost: None,
linked_site_removal_follow_on_gate_raw_u8: None,
linked_site_removal_follow_on_gate_enabled: None,
auto_show_grade_during_track_lay_raw_u8: None,
starting_building_density_level_raw_u8: None,
post_text_building_density_growth_raw_u8: None,
leftover_simulation_time_accumulator_raw_u32: None,
leftover_simulation_time_accumulator_value_f32_text: None,
selected_year_lane_snapshot_raw_u8: None,
all_steam_locomotives_available_raw_u8: None,
all_steam_locomotives_available_enabled: None,
all_diesel_locomotives_available_raw_u8: None,
@ -8865,6 +8942,195 @@ mod tests {
assert_eq!(runtime_company_annual_finance_state(&state, 99), None);
}
#[test]
fn derives_company_periodic_service_state_from_side_latches_and_world_route_preference() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1845,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState {
auto_show_grade_during_track_lay_raw_u8: Some(1),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 4,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: RuntimeCompanyControllerKind::Unknown,
linked_chairman_profile_id: None,
book_value_per_share: 0,
investor_confidence: 0,
management_attitude: 0,
takeover_cooldown_year: None,
merger_cooldown_year: None,
track_piece_counts: RuntimeTrackPieceCounts::default(),
}],
selected_company_id: Some(4),
players: Vec::new(),
selected_player_id: None,
chairman_profiles: Vec::new(),
selected_chairman_profile_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(),
packed_event_collection: None,
event_runtime_records: Vec::new(),
candidate_availability: BTreeMap::new(),
named_locomotive_availability: BTreeMap::new(),
named_locomotive_cost: BTreeMap::new(),
all_cargo_price_override: None,
named_cargo_price_overrides: BTreeMap::new(),
all_cargo_production_override: None,
factory_cargo_production_override: None,
farm_mine_cargo_production_override: None,
named_cargo_production_overrides: BTreeMap::new(),
cargo_production_overrides: BTreeMap::new(),
world_runtime_variables: BTreeMap::new(),
company_runtime_variables: BTreeMap::new(),
player_runtime_variables: BTreeMap::new(),
territory_runtime_variables: BTreeMap::new(),
world_scalar_overrides: BTreeMap::new(),
special_conditions: BTreeMap::new(),
service_state: RuntimeServiceState {
company_market_state: BTreeMap::from([(
4,
RuntimeCompanyMarketState {
city_connection_latch: true,
linked_transit_latch: false,
..RuntimeCompanyMarketState::default()
},
)]),
company_periodic_side_latch_state: BTreeMap::from([(
4,
RuntimeCompanyPeriodicSideLatchState {
preferred_locomotive_engine_type_raw_u8: Some(2),
city_connection_latch: false,
linked_transit_latch: true,
},
)]),
..RuntimeServiceState::default()
},
};
assert_eq!(
runtime_company_periodic_service_state(&state, 4),
Some(RuntimeCompanyPeriodicServiceState {
company_id: 4,
preferred_locomotive_engine_type_raw_u8: Some(2),
city_connection_latch: false,
linked_transit_latch: true,
base_route_preference_raw_u8: Some(1),
effective_route_preference_raw_u8: Some(2),
electric_route_preference_override_active: true,
effective_route_quality_multiplier_basis_points: 180,
})
);
assert_eq!(runtime_company_periodic_service_state(&state, 99), None);
}
#[test]
fn periodic_service_state_falls_back_to_market_latches_and_world_base_route_preference() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1845,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState {
auto_show_grade_during_track_lay_raw_u8: Some(3),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 8,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: RuntimeCompanyControllerKind::Unknown,
linked_chairman_profile_id: None,
book_value_per_share: 0,
investor_confidence: 0,
management_attitude: 0,
takeover_cooldown_year: None,
merger_cooldown_year: None,
track_piece_counts: RuntimeTrackPieceCounts::default(),
}],
selected_company_id: Some(8),
players: Vec::new(),
selected_player_id: None,
chairman_profiles: Vec::new(),
selected_chairman_profile_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(),
packed_event_collection: None,
event_runtime_records: Vec::new(),
candidate_availability: BTreeMap::new(),
named_locomotive_availability: BTreeMap::new(),
named_locomotive_cost: BTreeMap::new(),
all_cargo_price_override: None,
named_cargo_price_overrides: BTreeMap::new(),
all_cargo_production_override: None,
factory_cargo_production_override: None,
farm_mine_cargo_production_override: None,
named_cargo_production_overrides: BTreeMap::new(),
cargo_production_overrides: BTreeMap::new(),
world_runtime_variables: BTreeMap::new(),
company_runtime_variables: BTreeMap::new(),
player_runtime_variables: BTreeMap::new(),
territory_runtime_variables: BTreeMap::new(),
world_scalar_overrides: BTreeMap::new(),
special_conditions: BTreeMap::new(),
service_state: RuntimeServiceState {
company_market_state: BTreeMap::from([(
8,
RuntimeCompanyMarketState {
city_connection_latch: true,
linked_transit_latch: false,
..RuntimeCompanyMarketState::default()
},
)]),
..RuntimeServiceState::default()
},
};
assert_eq!(
runtime_company_periodic_service_state(&state, 8),
Some(RuntimeCompanyPeriodicServiceState {
company_id: 8,
preferred_locomotive_engine_type_raw_u8: None,
city_connection_latch: true,
linked_transit_latch: false,
base_route_preference_raw_u8: Some(3),
effective_route_preference_raw_u8: Some(3),
electric_route_preference_override_active: false,
effective_route_quality_multiplier_basis_points: 140,
})
);
}
#[test]
fn derives_annual_creditor_pressure_from_rehosted_finance_owner_state() {
let mut year_stat_family_qword_bits = vec![

View file

@ -2304,6 +2304,28 @@ pub struct SmpLoadedWorldLocomotivePolicyState {
#[serde(default)]
pub linked_site_removal_follow_on_gate_raw_hex: Option<String>,
#[serde(default)]
pub auto_show_grade_during_track_lay_raw_u8: Option<u8>,
#[serde(default)]
pub auto_show_grade_during_track_lay_raw_hex: Option<String>,
#[serde(default)]
pub starting_building_density_level_raw_u8: Option<u8>,
#[serde(default)]
pub starting_building_density_level_raw_hex: Option<String>,
#[serde(default)]
pub building_density_growth_raw_u8: Option<u8>,
#[serde(default)]
pub building_density_growth_raw_hex: Option<String>,
#[serde(default)]
pub leftover_simulation_time_accumulator_raw_u32: Option<u32>,
#[serde(default)]
pub leftover_simulation_time_accumulator_raw_hex: Option<String>,
#[serde(default)]
pub leftover_simulation_time_accumulator_value_f32_text: Option<String>,
#[serde(default)]
pub selected_year_lane_snapshot_raw_u8: Option<u8>,
#[serde(default)]
pub selected_year_lane_snapshot_raw_hex: Option<String>,
#[serde(default)]
pub all_steam_locomotives_available_raw_u8: Option<u8>,
#[serde(default)]
pub all_steam_locomotives_available_raw_hex: Option<String>,
@ -2932,10 +2954,10 @@ pub fn load_save_slice_from_report(
.save_world_finance_neighborhood_probe
.as_ref()
.map(derive_loaded_world_finance_neighborhood_state_from_probe);
let world_locomotive_policy_state = report
.locomotive_policy_neighborhood_probe
.as_ref()
.map(derive_loaded_world_locomotive_policy_state_from_probe);
let world_locomotive_policy_state = derive_loaded_world_locomotive_policy_state_from_probes(
report.post_text_field_neighborhood_probe.as_ref(),
report.locomotive_policy_neighborhood_probe.as_ref(),
);
let company_roster = report.save_company_roster_probe.clone().or_else(|| {
report
.save_world_selection_context_probe
@ -3638,23 +3660,37 @@ fn derive_loaded_world_finance_neighborhood_state_from_probe(
}
}
fn derive_loaded_world_locomotive_policy_state_from_probe(
probe: &SmpLocomotivePolicyNeighborhoodProbe,
) -> SmpLoadedWorldLocomotivePolicyState {
fn derive_loaded_world_locomotive_policy_state_from_probes(
post_text_probe: Option<&SmpPostTextFieldNeighborhoodProbe>,
locomotive_policy_probe: Option<&SmpLocomotivePolicyNeighborhoodProbe>,
) -> Option<SmpLoadedWorldLocomotivePolicyState> {
let field_by_name = |name: &str| {
probe
locomotive_policy_probe?
.grounded_field_observations
.iter()
.find(|field| field.field_name == name)
};
let post_text_field_by_name = |name: &str| {
post_text_probe?
.grounded_field_observations
.iter()
.find(|field| field.field_name == name)
};
let selected_year_gap_scalar = field_by_name("selected-year bucket companion scalar");
let linked_site_gate = field_by_name("linked-site removal follow-on gate");
let auto_show_grade = post_text_field_by_name("Auto-Show Grade During Track Lay");
let starting_building_density = post_text_field_by_name("Starting Building Density Level");
let building_density_growth = post_text_field_by_name("Building Density Growth");
let leftover_simulation_time = post_text_field_by_name("leftover simulation time accumulator");
let selected_year_snapshot = post_text_field_by_name("selected-year lane snapshot");
let all_steam = field_by_name("All Steam Locos Avail.");
let all_diesel = field_by_name("All Diesel Locos Avail.");
let all_electric = field_by_name("All Electric Locos Avail.");
let cached_available_rating = field_by_name("cached available-locomotive rating");
SmpLoadedWorldLocomotivePolicyState {
source_kind: probe.source_kind.clone(),
Some(SmpLoadedWorldLocomotivePolicyState {
source_kind: locomotive_policy_probe
.map(|probe| probe.source_kind.clone())
.or_else(|| post_text_probe.map(|probe| probe.source_kind.clone()))?,
semantic_family: "world-locomotive-policy".to_string(),
selected_year_gap_scalar_raw_u32: selected_year_gap_scalar
.and_then(|field| field.value_u32),
@ -3666,6 +3702,25 @@ fn derive_loaded_world_locomotive_policy_state_from_probe(
.and_then(|field| field.value_u8),
linked_site_removal_follow_on_gate_raw_hex: linked_site_gate
.and_then(|field| field.value_u8_hex.clone()),
auto_show_grade_during_track_lay_raw_u8: auto_show_grade.and_then(|field| field.value_u8),
auto_show_grade_during_track_lay_raw_hex: auto_show_grade
.and_then(|field| field.value_u8_hex.clone()),
starting_building_density_level_raw_u8: starting_building_density
.and_then(|field| field.value_u8),
starting_building_density_level_raw_hex: starting_building_density
.and_then(|field| field.value_u8_hex.clone()),
building_density_growth_raw_u8: building_density_growth.and_then(|field| field.value_u8),
building_density_growth_raw_hex: building_density_growth
.and_then(|field| field.value_u8_hex.clone()),
leftover_simulation_time_accumulator_raw_u32: leftover_simulation_time
.and_then(|field| field.value_u32),
leftover_simulation_time_accumulator_raw_hex: leftover_simulation_time
.and_then(|field| field.value_u32_hex.clone()),
leftover_simulation_time_accumulator_value_f32_text: leftover_simulation_time
.and_then(|field| field.probable_f32_le.clone()),
selected_year_lane_snapshot_raw_u8: selected_year_snapshot.and_then(|field| field.value_u8),
selected_year_lane_snapshot_raw_hex: selected_year_snapshot
.and_then(|field| field.value_u8_hex.clone()),
all_steam_locomotives_available_raw_u8: all_steam.and_then(|field| field.value_u8),
all_steam_locomotives_available_raw_hex: all_steam
.and_then(|field| field.value_u8_hex.clone()),
@ -3681,7 +3736,7 @@ fn derive_loaded_world_locomotive_policy_state_from_probe(
.and_then(|field| field.value_u32_hex.clone()),
cached_available_locomotive_rating_value_f32_text: cached_available_rating
.and_then(|field| field.probable_f32_le.clone()),
}
})
}
fn derive_selection_only_company_roster_from_save_world_probe(

View file

@ -7,7 +7,7 @@ use crate::{
runtime_company_annual_finance_policy_action_label,
runtime_company_annual_finance_policy_state, runtime_company_annual_finance_state,
runtime_company_annual_stock_issue_state, runtime_company_annual_stock_repurchase_state,
runtime_company_unassigned_share_pool,
runtime_company_periodic_service_state, runtime_company_unassigned_share_pool,
};
fn raw_u32_to_f32_text(raw: u32) -> String {
@ -51,6 +51,12 @@ pub struct RuntimeSummary {
pub world_restore_territory_access_cost: Option<u32>,
pub world_restore_linked_site_removal_follow_on_gate_raw_u8: Option<u8>,
pub world_restore_linked_site_removal_follow_on_gate_enabled: Option<bool>,
pub world_restore_auto_show_grade_during_track_lay_raw_u8: Option<u8>,
pub world_restore_starting_building_density_level_raw_u8: Option<u8>,
pub world_restore_post_text_building_density_growth_raw_u8: Option<u8>,
pub world_restore_leftover_simulation_time_accumulator_raw_u32: Option<u32>,
pub world_restore_leftover_simulation_time_accumulator_value_f32_text: Option<String>,
pub world_restore_selected_year_lane_snapshot_raw_u8: Option<u8>,
pub world_restore_all_steam_locomotives_available_raw_u8: Option<u8>,
pub world_restore_all_steam_locomotives_available_enabled: Option<bool>,
pub world_restore_all_diesel_locomotives_available_raw_u8: Option<u8>,
@ -122,6 +128,10 @@ pub struct RuntimeSummary {
pub selected_company_periodic_side_latch_preferred_locomotive_engine_type_raw_u8: Option<u8>,
pub selected_company_periodic_side_latch_city_connection_latch: Option<bool>,
pub selected_company_periodic_side_latch_linked_transit_latch: Option<bool>,
pub selected_company_periodic_service_base_route_preference_raw_u8: Option<u8>,
pub selected_company_periodic_service_effective_route_preference_raw_u8: Option<u8>,
pub selected_company_periodic_service_electric_route_preference_override_active: Option<bool>,
pub selected_company_periodic_service_route_quality_multiplier_basis_points: Option<i64>,
pub selected_company_chairman_bonus_year: Option<u32>,
pub selected_company_chairman_bonus_amount: Option<i32>,
pub selected_company_creditor_pressure_recent_bad_net_profit_year_count: Option<u32>,
@ -307,6 +317,9 @@ impl RuntimeSummary {
.company_periodic_side_latch_state
.get(&company_id)
});
let selected_company_periodic_service_state = state
.selected_company_id
.and_then(|company_id| runtime_company_periodic_service_state(state, company_id));
let selected_company_annual_finance_state = state
.selected_company_id
.and_then(|company_id| runtime_company_annual_finance_state(state, company_id));
@ -464,6 +477,25 @@ impl RuntimeSummary {
world_restore_linked_site_removal_follow_on_gate_enabled: state
.world_restore
.linked_site_removal_follow_on_gate_enabled,
world_restore_auto_show_grade_during_track_lay_raw_u8: state
.world_restore
.auto_show_grade_during_track_lay_raw_u8,
world_restore_starting_building_density_level_raw_u8: state
.world_restore
.starting_building_density_level_raw_u8,
world_restore_post_text_building_density_growth_raw_u8: state
.world_restore
.post_text_building_density_growth_raw_u8,
world_restore_leftover_simulation_time_accumulator_raw_u32: state
.world_restore
.leftover_simulation_time_accumulator_raw_u32,
world_restore_leftover_simulation_time_accumulator_value_f32_text: state
.world_restore
.leftover_simulation_time_accumulator_value_f32_text
.clone(),
world_restore_selected_year_lane_snapshot_raw_u8: state
.world_restore
.selected_year_lane_snapshot_raw_u8,
world_restore_all_steam_locomotives_available_raw_u8: state
.world_restore
.all_steam_locomotives_available_raw_u8,
@ -622,6 +654,24 @@ impl RuntimeSummary {
selected_company_periodic_side_latch_linked_transit_latch:
selected_company_periodic_side_latch_state
.map(|latch_state| latch_state.linked_transit_latch),
selected_company_periodic_service_base_route_preference_raw_u8:
selected_company_periodic_service_state
.as_ref()
.and_then(|service_state| service_state.base_route_preference_raw_u8),
selected_company_periodic_service_effective_route_preference_raw_u8:
selected_company_periodic_service_state
.as_ref()
.and_then(|service_state| service_state.effective_route_preference_raw_u8),
selected_company_periodic_service_electric_route_preference_override_active:
selected_company_periodic_service_state
.as_ref()
.map(|service_state| service_state.electric_route_preference_override_active),
selected_company_periodic_service_route_quality_multiplier_basis_points:
selected_company_periodic_service_state
.as_ref()
.map(|service_state| {
service_state.effective_route_quality_multiplier_basis_points
}),
selected_company_chairman_bonus_year: selected_company_market_state
.map(|market_state| market_state.chairman_bonus_year)
.filter(|year| *year != 0),
@ -1578,7 +1628,10 @@ mod tests {
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState::default(),
world_restore: RuntimeWorldRestoreState {
auto_show_grade_during_track_lay_raw_u8: Some(2),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
@ -1857,6 +1910,12 @@ mod tests {
],
linked_site_removal_follow_on_gate_raw_u8: Some(1),
linked_site_removal_follow_on_gate_enabled: Some(true),
auto_show_grade_during_track_lay_raw_u8: Some(2),
starting_building_density_level_raw_u8: Some(3),
post_text_building_density_growth_raw_u8: Some(1),
leftover_simulation_time_accumulator_raw_u32: Some(0x3f000000),
leftover_simulation_time_accumulator_value_f32_text: Some("0.500000".to_string()),
selected_year_lane_snapshot_raw_u8: Some(7),
all_steam_locomotives_available_raw_u8: Some(1),
all_steam_locomotives_available_enabled: Some(true),
all_diesel_locomotives_available_raw_u8: Some(0),
@ -2017,6 +2076,32 @@ mod tests {
summary.world_restore_linked_site_removal_follow_on_gate_enabled,
Some(true)
);
assert_eq!(
summary.world_restore_auto_show_grade_during_track_lay_raw_u8,
Some(2)
);
assert_eq!(
summary.world_restore_starting_building_density_level_raw_u8,
Some(3)
);
assert_eq!(
summary.world_restore_post_text_building_density_growth_raw_u8,
Some(1)
);
assert_eq!(
summary.world_restore_leftover_simulation_time_accumulator_raw_u32,
Some(0x3f000000)
);
assert_eq!(
summary
.world_restore_leftover_simulation_time_accumulator_value_f32_text
.as_deref(),
Some("0.500000")
);
assert_eq!(
summary.world_restore_selected_year_lane_snapshot_raw_u8,
Some(7)
);
assert_eq!(
summary.world_restore_all_steam_locomotives_available_raw_u8,
Some(1)
@ -2113,7 +2198,10 @@ mod tests {
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState::default(),
world_restore: RuntimeWorldRestoreState {
auto_show_grade_during_track_lay_raw_u8: Some(2),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![
RuntimeCompany {
@ -2218,7 +2306,10 @@ mod tests {
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState::default(),
world_restore: RuntimeWorldRestoreState {
auto_show_grade_during_track_lay_raw_u8: Some(2),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
@ -2770,7 +2861,10 @@ mod tests {
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState::default(),
world_restore: RuntimeWorldRestoreState {
auto_show_grade_during_track_lay_raw_u8: Some(2),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 1,
@ -2972,6 +3066,22 @@ mod tests {
summary.selected_company_periodic_side_latch_linked_transit_latch,
Some(false)
);
assert_eq!(
summary.selected_company_periodic_service_base_route_preference_raw_u8,
Some(2)
);
assert_eq!(
summary.selected_company_periodic_service_effective_route_preference_raw_u8,
Some(2)
);
assert_eq!(
summary.selected_company_periodic_service_electric_route_preference_override_active,
Some(true)
);
assert_eq!(
summary.selected_company_periodic_service_route_quality_multiplier_basis_points,
Some(180)
);
assert_eq!(summary.selected_company_chairman_bonus_year, Some(1842));
assert_eq!(summary.selected_company_chairman_bonus_amount, Some(750));
}