rrt/crates/rrt-runtime/src/summary.rs

4143 lines
193 KiB
Rust

use serde::{Deserialize, Serialize};
use crate::{
CalendarPoint, RuntimeState, runtime_annual_bond_principal_flow_relation_label,
runtime_company_annual_bond_policy_state, runtime_company_annual_creditor_pressure_state,
runtime_company_annual_deep_distress_state, runtime_company_annual_dividend_policy_state,
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_periodic_service_state, runtime_company_unassigned_share_pool,
};
fn raw_u32_to_f32_text(raw: u32) -> String {
format!("{:.6}", f32::from_bits(raw))
}
fn raw_u64_to_f64_text(raw: u64) -> String {
format!("{:.6}", f64::from_bits(raw))
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeSummary {
pub calendar: CalendarPoint,
pub calendar_projection_source: Option<String>,
pub calendar_projection_is_placeholder: bool,
pub world_flag_count: usize,
pub world_restore_selected_year_profile_lane: Option<u8>,
pub world_restore_campaign_scenario_enabled: Option<bool>,
pub world_restore_sandbox_enabled: Option<bool>,
pub world_restore_seed_tuple_written_from_raw_lane: Option<bool>,
pub world_restore_absolute_counter_requires_shell_context: Option<bool>,
pub world_restore_absolute_counter_reconstructible_from_save: Option<bool>,
pub world_restore_packed_year_word_raw_u16: Option<u16>,
pub world_restore_partial_year_progress_raw_u8: Option<u8>,
pub world_restore_current_calendar_tuple_word_raw_u32: Option<u32>,
pub world_restore_current_calendar_tuple_word_2_raw_u32: Option<u32>,
pub world_restore_absolute_counter_raw_u32: Option<u32>,
pub world_restore_absolute_counter_mirror_raw_u32: Option<u32>,
pub world_restore_disable_cargo_economy_special_condition_slot: Option<u8>,
pub world_restore_disable_cargo_economy_special_condition_reconstructible_from_save:
Option<bool>,
pub world_restore_disable_cargo_economy_special_condition_write_side_grounded: Option<bool>,
pub world_restore_disable_cargo_economy_special_condition_enabled: Option<bool>,
pub world_restore_use_bio_accelerator_cars_enabled: Option<bool>,
pub world_restore_use_wartime_cargos_enabled: Option<bool>,
pub world_restore_disable_train_crashes_enabled: Option<bool>,
pub world_restore_disable_train_crashes_and_breakdowns_enabled: Option<bool>,
pub world_restore_ai_ignore_territories_at_startup_enabled: Option<bool>,
pub world_restore_limited_track_building_amount: Option<i32>,
pub world_restore_economic_status_code: Option<i32>,
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>,
pub world_restore_all_diesel_locomotives_available_enabled: Option<bool>,
pub world_restore_all_electric_locomotives_available_raw_u8: Option<u8>,
pub world_restore_all_electric_locomotives_available_enabled: Option<bool>,
pub world_restore_issue_37_value: Option<u32>,
pub world_restore_issue_38_value: Option<u32>,
pub world_restore_issue_39_value: Option<u32>,
pub world_restore_issue_3a_value: Option<u32>,
pub world_restore_issue_37_multiplier_raw_u32: Option<u32>,
pub world_restore_issue_37_multiplier_value_f32_text: Option<String>,
pub world_restore_stock_issue_and_buyback_policy_raw_u8: Option<u8>,
pub world_restore_bond_issue_and_repayment_policy_raw_u8: Option<u8>,
pub world_restore_bankruptcy_policy_raw_u8: Option<u8>,
pub world_restore_dividend_policy_raw_u8: Option<u8>,
pub world_restore_building_density_growth_setting_raw_u32: Option<u32>,
pub world_restore_stock_issue_and_buyback_allowed: Option<bool>,
pub world_restore_bond_issue_and_repayment_allowed: Option<bool>,
pub world_restore_bankruptcy_allowed: Option<bool>,
pub world_restore_dividend_adjustment_allowed: Option<bool>,
pub world_restore_finance_neighborhood_count: usize,
pub world_restore_finance_neighborhood_labels: Vec<String>,
pub world_restore_economic_tuning_mirror_raw_u32: Option<u32>,
pub world_restore_economic_tuning_mirror_value_f32_text: Option<String>,
pub world_restore_economic_tuning_lane_count: usize,
pub world_restore_economic_tuning_lane_value_f32_text: Vec<String>,
pub world_restore_cached_available_locomotive_rating_raw_u32: Option<u32>,
pub world_restore_cached_available_locomotive_rating_value_f32_text: Option<String>,
pub world_restore_selected_year_bucket_scalar_raw_u32: Option<u32>,
pub world_restore_selected_year_bucket_scalar_value_f32_text: Option<String>,
pub world_restore_selected_year_bucket_direct_lane_count: usize,
pub world_restore_selected_year_bucket_direct_lane_value_f32_text: Vec<String>,
pub world_restore_selected_year_bucket_complement_lane_count: usize,
pub world_restore_selected_year_bucket_complement_lane_value_f32_text: Vec<String>,
pub world_restore_selected_year_bucket_scaled_companion_lane_count: usize,
pub world_restore_selected_year_bucket_scaled_companion_lane_value_f32_text: Vec<String>,
pub world_restore_selected_year_gap_scalar_raw_u32: Option<u32>,
pub world_restore_selected_year_gap_scalar_value_f32_text: Option<String>,
pub world_restore_absolute_counter_restore_kind: Option<String>,
pub world_restore_absolute_counter_adjustment_context: Option<String>,
pub metadata_count: usize,
pub company_count: usize,
pub active_company_count: usize,
pub company_market_state_owner_count: usize,
pub selected_company_outstanding_shares: Option<u32>,
pub selected_company_bond_count: Option<u8>,
pub selected_company_largest_live_bond_principal: Option<u32>,
pub selected_company_highest_coupon_live_bond_principal: Option<u32>,
pub selected_company_assigned_share_pool: Option<u32>,
pub selected_company_unassigned_share_pool: Option<u32>,
pub selected_company_cached_share_price: Option<i64>,
pub selected_company_cached_share_price_value_f32_text: Option<String>,
pub selected_company_recent_per_share_cache_absolute_counter: Option<u32>,
pub selected_company_recent_per_share_cached_value_f64_text: Option<String>,
pub selected_company_recent_per_share_subscore_value_f32_text: Option<String>,
pub selected_company_mutable_support_scalar_value_f32_text: Option<String>,
pub selected_company_stat_band_root_0cfb_count: usize,
pub selected_company_stat_band_root_0d7f_count: usize,
pub selected_company_stat_band_root_1c47_count: usize,
pub selected_company_last_dividend_year: Option<u32>,
pub selected_company_years_since_founding: Option<u32>,
pub selected_company_years_since_last_bankruptcy: Option<u32>,
pub selected_company_years_since_last_dividend: Option<u32>,
pub selected_company_current_partial_year_weight_numerator: Option<i64>,
pub selected_company_current_issue_absolute_counter: Option<u32>,
pub selected_company_prior_issue_absolute_counter: Option<u32>,
pub selected_company_current_issue_age_absolute_counter_delta: Option<i64>,
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 active_periodic_route_preference_override_company_id: Option<u32>,
pub active_periodic_route_preference_override_effective_raw_u8: Option<u8>,
pub last_periodic_route_preference_override_company_id: Option<u32>,
pub last_periodic_route_preference_override_effective_raw_u8: Option<u8>,
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>,
pub selected_company_creditor_pressure_recent_peak_revenue: Option<i64>,
pub selected_company_creditor_pressure_recent_three_year_net_profit_total: Option<i64>,
pub selected_company_creditor_pressure_cash_floor: Option<i64>,
pub selected_company_creditor_pressure_cash_plus_slot_12_total: Option<i64>,
pub selected_company_creditor_pressure_share_price_floor: Option<i64>,
pub selected_company_creditor_pressure_share_price_scalar: Option<i64>,
pub selected_company_creditor_pressure_current_fuel_cost: Option<i64>,
pub selected_company_creditor_pressure_current_fuel_cost_floor: Option<i64>,
pub selected_company_creditor_pressure_eligible_for_bankruptcy_branch: Option<bool>,
pub selected_company_deep_distress_current_cash: Option<i64>,
pub selected_company_deep_distress_recent_first_three_net_profit_years: Vec<i64>,
pub selected_company_deep_distress_cash_floor: Option<i64>,
pub selected_company_deep_distress_net_profit_floor: Option<i64>,
pub selected_company_deep_distress_eligible_for_bankruptcy_fallback: Option<bool>,
pub selected_company_annual_bond_linked_transit_latch: Option<bool>,
pub selected_company_annual_bond_live_bond_count: Option<u8>,
pub selected_company_annual_bond_live_bond_principal_total: Option<u32>,
pub selected_company_annual_bond_matured_live_bond_count: Option<u32>,
pub selected_company_annual_bond_matured_live_bond_principal_total: Option<u32>,
pub selected_company_annual_bond_next_live_bond_maturity_year: Option<u32>,
pub selected_company_annual_bond_live_bond_coupon_burden_total: Option<i64>,
pub selected_company_annual_bond_current_cash: Option<i64>,
pub selected_company_annual_bond_cash_after_full_repayment: Option<i64>,
pub selected_company_annual_bond_issue_cash_floor: Option<i64>,
pub selected_company_annual_bond_issue_principal_step: Option<u32>,
pub selected_company_annual_bond_proposed_issue_bond_count: Option<u32>,
pub selected_company_annual_bond_proposed_issue_total_principal: Option<u32>,
pub selected_company_annual_bond_proposed_issue_years_to_maturity: Option<u32>,
pub selected_company_annual_bond_eligible_for_issue_branch: Option<bool>,
pub selected_company_stock_repurchase_city_connection_latch: Option<bool>,
pub selected_company_stock_repurchase_building_density_growth_setting: Option<u32>,
pub selected_company_stock_repurchase_linked_chairman_profile_id: Option<u32>,
pub selected_company_stock_repurchase_linked_chairman_personality_raw_u8: Option<u8>,
pub selected_company_stock_repurchase_batch_size: Option<u32>,
pub selected_company_stock_repurchase_factor_basis_points: Option<i64>,
pub selected_company_stock_repurchase_current_cash: Option<i64>,
pub selected_company_stock_repurchase_stock_value_gate_cash_floor: Option<i64>,
pub selected_company_stock_repurchase_support_adjusted_share_price_scalar: Option<i64>,
pub selected_company_stock_repurchase_affordability_cash_floor: Option<i64>,
pub selected_company_stock_repurchase_unassigned_share_pool: Option<u32>,
pub selected_company_stock_repurchase_eligible_for_single_batch: Option<bool>,
pub selected_company_stock_issue_live_bond_count: Option<u8>,
pub selected_company_stock_issue_initial_batch_size: Option<u32>,
pub selected_company_stock_issue_trimmed_batch_size: Option<u32>,
pub selected_company_stock_issue_share_pressure_basis_points: Option<i64>,
pub selected_company_stock_issue_pressured_share_price_scalar: Option<i64>,
pub selected_company_stock_issue_pressured_proceeds: Option<i64>,
pub selected_company_stock_issue_book_value_per_share_floor_applied: Option<i64>,
pub selected_company_stock_issue_price_to_book_ratio_basis_points: Option<i64>,
pub selected_company_stock_issue_current_cash: Option<i64>,
pub selected_company_stock_issue_highest_coupon_live_bond_principal: Option<u32>,
pub selected_company_stock_issue_highest_coupon_live_bond_rate_basis_points: Option<i64>,
pub selected_company_stock_issue_current_issue_age_absolute_counter_delta: Option<i64>,
pub selected_company_stock_issue_current_issue_cooldown_floor: Option<i64>,
pub selected_company_stock_issue_minimum_price_to_book_ratio_basis_points: Option<i64>,
pub selected_company_stock_issue_passes_share_price_floor: Option<bool>,
pub selected_company_stock_issue_passes_proceeds_floor: Option<bool>,
pub selected_company_stock_issue_passes_cash_gate: Option<bool>,
pub selected_company_stock_issue_passes_issue_cooldown_gate: Option<bool>,
pub selected_company_stock_issue_passes_coupon_price_to_book_gate: Option<bool>,
pub selected_company_stock_issue_eligible_for_double_tranche: Option<bool>,
pub selected_company_dividend_weighted_recent_net_profit_total: Option<i64>,
pub selected_company_dividend_weighted_recent_net_profit_average: Option<i64>,
pub selected_company_dividend_current_cash: Option<i64>,
pub selected_company_dividend_tiny_unassigned_share_cash_supplement_branch: Option<bool>,
pub selected_company_dividend_tentative_target_per_share_tenths: Option<i64>,
pub selected_company_dividend_current_per_share_tenths: Option<i64>,
pub selected_company_dividend_growth_adjusted_current_per_share_tenths: Option<i64>,
pub selected_company_dividend_board_approved_ceiling_tenths: Option<i64>,
pub selected_company_dividend_proposed_per_share_tenths: Option<i64>,
pub selected_company_dividend_eligible_for_adjustment_branch: Option<bool>,
pub selected_company_annual_finance_policy_action: Option<String>,
pub selected_company_annual_finance_news_family_candidate: Option<String>,
pub selected_company_annual_finance_last_news_selector: Option<String>,
pub annual_finance_last_news_event_count: usize,
pub selected_company_annual_finance_policy_creditor_pressure_bankruptcy_eligible: Option<bool>,
pub selected_company_annual_finance_policy_deep_distress_bankruptcy_fallback_eligible:
Option<bool>,
pub selected_company_annual_finance_policy_bond_issue_eligible: Option<bool>,
pub selected_company_annual_finance_policy_stock_repurchase_eligible: Option<bool>,
pub selected_company_annual_finance_policy_stock_issue_eligible: Option<bool>,
pub selected_company_annual_finance_policy_dividend_adjustment_eligible: Option<bool>,
pub player_count: usize,
pub chairman_profile_count: usize,
pub active_chairman_profile_count: usize,
pub selected_chairman_profile_id: Option<u32>,
pub linked_chairman_company_count: usize,
pub company_takeover_cooldown_count: usize,
pub company_merger_cooldown_count: usize,
pub train_count: usize,
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,
pub packed_event_record_count: usize,
pub packed_event_decoded_record_count: usize,
pub packed_event_imported_runtime_record_count: usize,
pub packed_event_parity_only_record_count: usize,
pub packed_event_unsupported_record_count: usize,
pub packed_event_blocked_missing_company_context_count: usize,
pub packed_event_blocked_missing_selection_context_count: usize,
pub packed_event_blocked_missing_company_role_context_count: usize,
pub packed_event_blocked_missing_player_context_count: usize,
pub packed_event_blocked_missing_player_selection_context_count: usize,
pub packed_event_blocked_missing_player_role_context_count: usize,
pub packed_event_blocked_missing_chairman_context_count: usize,
pub packed_event_blocked_chairman_target_scope_count: usize,
pub packed_event_blocked_missing_condition_context_count: usize,
pub packed_event_blocked_missing_player_condition_context_count: usize,
pub packed_event_blocked_company_condition_scope_disabled_count: usize,
pub packed_event_blocked_player_condition_scope_count: usize,
pub packed_event_blocked_territory_condition_scope_count: usize,
pub packed_event_blocked_missing_territory_context_count: usize,
pub packed_event_blocked_named_territory_binding_count: usize,
pub packed_event_blocked_unmapped_ordinary_condition_count: usize,
pub packed_event_blocked_unmapped_world_condition_count: usize,
pub packed_event_blocked_missing_compact_control_count: usize,
pub packed_event_blocked_shell_owned_descriptor_count: usize,
pub packed_event_blocked_evidence_blocked_descriptor_count: usize,
pub packed_event_blocked_variant_or_scope_blocked_descriptor_count: usize,
pub packed_event_blocked_unmapped_real_descriptor_count: usize,
pub packed_event_blocked_unmapped_world_descriptor_count: usize,
pub packed_event_blocked_territory_access_variant_count: usize,
pub packed_event_blocked_territory_access_scope_count: usize,
pub packed_event_blocked_missing_train_context_count: usize,
pub packed_event_blocked_missing_train_territory_context_count: usize,
pub packed_event_blocked_missing_locomotive_catalog_context_count: usize,
pub packed_event_blocked_confiscation_variant_count: usize,
pub packed_event_blocked_retire_train_variant_count: usize,
pub packed_event_blocked_retire_train_scope_count: usize,
pub packed_event_blocked_structural_only_count: usize,
pub event_runtime_record_count: usize,
pub candidate_availability_count: usize,
pub zero_candidate_availability_count: usize,
pub named_locomotive_availability_count: usize,
pub zero_named_locomotive_availability_count: usize,
pub named_locomotive_cost_count: usize,
pub cargo_production_override_count: usize,
pub world_runtime_variable_count: usize,
pub company_runtime_variable_owner_count: usize,
pub player_runtime_variable_owner_count: usize,
pub territory_runtime_variable_owner_count: usize,
pub world_scalar_override_count: usize,
pub special_condition_count: usize,
pub enabled_special_condition_count: usize,
pub save_profile_kind: Option<String>,
pub save_profile_family: Option<String>,
pub save_profile_map_path: Option<String>,
pub save_profile_display_name: Option<String>,
pub save_profile_selected_year_profile_lane: Option<u8>,
pub save_profile_sandbox_enabled: Option<bool>,
pub save_profile_campaign_scenario_enabled: Option<bool>,
pub save_profile_staged_profile_copy_on_restore: Option<bool>,
pub total_event_record_service_count: u64,
pub periodic_boundary_call_count: u64,
pub annual_finance_service_call_count: u64,
pub periodic_route_preference_override_apply_count: u64,
pub periodic_route_preference_override_restore_count: u64,
pub annual_dividend_adjustment_commit_count: u64,
pub annual_bond_last_retired_principal_total: u64,
pub annual_bond_last_issued_principal_total: u64,
pub annual_bond_last_principal_flow_relation: Option<String>,
pub annual_stock_repurchase_last_share_count: u64,
pub annual_stock_issue_last_share_count: u64,
pub total_trigger_dispatch_count: u64,
pub dirty_rerun_count: u64,
pub total_company_cash: i64,
}
impl RuntimeSummary {
pub fn from_state(state: &RuntimeState) -> Self {
let selected_company_market_state = state
.selected_company_id
.and_then(|company_id| state.service_state.company_market_state.get(&company_id));
let selected_company_periodic_side_latch_state =
state.selected_company_id.and_then(|company_id| {
state
.service_state
.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));
let selected_company_creditor_pressure_state =
state.selected_company_id.and_then(|company_id| {
runtime_company_annual_creditor_pressure_state(state, company_id)
});
let selected_company_deep_distress_state = state
.selected_company_id
.and_then(|company_id| runtime_company_annual_deep_distress_state(state, company_id));
let selected_company_annual_bond_state = state
.selected_company_id
.and_then(|company_id| runtime_company_annual_bond_policy_state(state, company_id));
let selected_company_stock_repurchase_state =
state.selected_company_id.and_then(|company_id| {
runtime_company_annual_stock_repurchase_state(state, company_id)
});
let selected_company_stock_issue_state = state
.selected_company_id
.and_then(|company_id| runtime_company_annual_stock_issue_state(state, company_id));
let selected_company_dividend_state = state
.selected_company_id
.and_then(|company_id| runtime_company_annual_dividend_policy_state(state, company_id));
let selected_company_annual_finance_policy_state = state
.selected_company_id
.and_then(|company_id| runtime_company_annual_finance_policy_state(state, company_id));
Self {
calendar: state.calendar,
calendar_projection_source: state.metadata.get("save_slice.calendar_source").cloned(),
calendar_projection_is_placeholder: state
.metadata
.get("save_slice.calendar_source")
.is_some_and(|value| value == "default-1830-placeholder"),
world_flag_count: state.world_flags.len(),
world_restore_selected_year_profile_lane: state
.world_restore
.selected_year_profile_lane,
world_restore_campaign_scenario_enabled: state.world_restore.campaign_scenario_enabled,
world_restore_sandbox_enabled: state.world_restore.sandbox_enabled,
world_restore_seed_tuple_written_from_raw_lane: state
.world_restore
.seed_tuple_written_from_raw_lane,
world_restore_absolute_counter_requires_shell_context: state
.world_restore
.absolute_counter_requires_shell_context,
world_restore_absolute_counter_reconstructible_from_save: state
.world_restore
.absolute_counter_reconstructible_from_save,
world_restore_packed_year_word_raw_u16: state.world_restore.packed_year_word_raw_u16,
world_restore_partial_year_progress_raw_u8: state
.world_restore
.partial_year_progress_raw_u8,
world_restore_current_calendar_tuple_word_raw_u32: state
.world_restore
.current_calendar_tuple_word_raw_u32,
world_restore_current_calendar_tuple_word_2_raw_u32: state
.world_restore
.current_calendar_tuple_word_2_raw_u32,
world_restore_absolute_counter_raw_u32: state.world_restore.absolute_counter_raw_u32,
world_restore_absolute_counter_mirror_raw_u32: state
.world_restore
.absolute_counter_mirror_raw_u32,
world_restore_disable_cargo_economy_special_condition_slot: state
.world_restore
.disable_cargo_economy_special_condition_slot,
world_restore_disable_cargo_economy_special_condition_reconstructible_from_save: state
.world_restore
.disable_cargo_economy_special_condition_reconstructible_from_save,
world_restore_disable_cargo_economy_special_condition_write_side_grounded: state
.world_restore
.disable_cargo_economy_special_condition_write_side_grounded,
world_restore_disable_cargo_economy_special_condition_enabled: state
.world_restore
.disable_cargo_economy_special_condition_enabled,
world_restore_use_bio_accelerator_cars_enabled: state
.world_restore
.use_bio_accelerator_cars_enabled,
world_restore_use_wartime_cargos_enabled: state
.world_restore
.use_wartime_cargos_enabled,
world_restore_disable_train_crashes_enabled: state
.world_restore
.disable_train_crashes_enabled,
world_restore_disable_train_crashes_and_breakdowns_enabled: state
.world_restore
.disable_train_crashes_and_breakdowns_enabled,
world_restore_ai_ignore_territories_at_startup_enabled: state
.world_restore
.ai_ignore_territories_at_startup_enabled,
world_restore_limited_track_building_amount: state
.world_restore
.limited_track_building_amount,
world_restore_economic_status_code: state.world_restore.economic_status_code,
world_restore_territory_access_cost: state.world_restore.territory_access_cost,
world_restore_issue_37_value: state.world_restore.issue_37_value,
world_restore_issue_38_value: state.world_restore.issue_38_value,
world_restore_issue_39_value: state.world_restore.issue_39_value,
world_restore_issue_3a_value: state.world_restore.issue_3a_value,
world_restore_issue_37_multiplier_raw_u32: state
.world_restore
.issue_37_multiplier_raw_u32,
world_restore_issue_37_multiplier_value_f32_text: state
.world_restore
.issue_37_multiplier_value_f32_text
.clone(),
world_restore_stock_issue_and_buyback_policy_raw_u8: state
.world_restore
.stock_issue_and_buyback_policy_raw_u8,
world_restore_bond_issue_and_repayment_policy_raw_u8: state
.world_restore
.bond_issue_and_repayment_policy_raw_u8,
world_restore_bankruptcy_policy_raw_u8: state.world_restore.bankruptcy_policy_raw_u8,
world_restore_dividend_policy_raw_u8: state.world_restore.dividend_policy_raw_u8,
world_restore_building_density_growth_setting_raw_u32: state
.world_restore
.building_density_growth_setting_raw_u32,
world_restore_stock_issue_and_buyback_allowed: state
.world_restore
.stock_issue_and_buyback_allowed,
world_restore_bond_issue_and_repayment_allowed: state
.world_restore
.bond_issue_and_repayment_allowed,
world_restore_bankruptcy_allowed: state.world_restore.bankruptcy_allowed,
world_restore_dividend_adjustment_allowed: state
.world_restore
.dividend_adjustment_allowed,
world_restore_finance_neighborhood_count: state
.world_restore
.finance_neighborhood_candidates
.len(),
world_restore_finance_neighborhood_labels: state
.world_restore
.finance_neighborhood_candidates
.iter()
.map(|candidate| candidate.label.clone())
.collect(),
world_restore_economic_tuning_mirror_raw_u32: state
.world_restore
.economic_tuning_mirror_raw_u32,
world_restore_economic_tuning_mirror_value_f32_text: state
.world_restore
.economic_tuning_mirror_value_f32_text
.clone(),
world_restore_economic_tuning_lane_count: state
.world_restore
.economic_tuning_lane_raw_u32
.len(),
world_restore_economic_tuning_lane_value_f32_text: state
.world_restore
.economic_tuning_lane_value_f32_text
.clone(),
world_restore_linked_site_removal_follow_on_gate_raw_u8: state
.world_restore
.linked_site_removal_follow_on_gate_raw_u8,
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,
world_restore_all_steam_locomotives_available_enabled: state
.world_restore
.all_steam_locomotives_available_enabled,
world_restore_all_diesel_locomotives_available_raw_u8: state
.world_restore
.all_diesel_locomotives_available_raw_u8,
world_restore_all_diesel_locomotives_available_enabled: state
.world_restore
.all_diesel_locomotives_available_enabled,
world_restore_all_electric_locomotives_available_raw_u8: state
.world_restore
.all_electric_locomotives_available_raw_u8,
world_restore_all_electric_locomotives_available_enabled: state
.world_restore
.all_electric_locomotives_available_enabled,
world_restore_cached_available_locomotive_rating_raw_u32: state
.world_restore
.cached_available_locomotive_rating_raw_u32,
world_restore_cached_available_locomotive_rating_value_f32_text: state
.world_restore
.cached_available_locomotive_rating_value_f32_text
.clone(),
world_restore_selected_year_bucket_scalar_raw_u32: state
.world_restore
.selected_year_bucket_scalar_raw_u32,
world_restore_selected_year_bucket_scalar_value_f32_text: state
.world_restore
.selected_year_bucket_scalar_value_f32_text
.clone(),
world_restore_selected_year_bucket_direct_lane_count: state
.world_restore
.selected_year_bucket_direct_lane_raw_u32
.len(),
world_restore_selected_year_bucket_direct_lane_value_f32_text: state
.world_restore
.selected_year_bucket_direct_lane_value_f32_text
.clone(),
world_restore_selected_year_bucket_complement_lane_count: state
.world_restore
.selected_year_bucket_complement_lane_raw_u32
.len(),
world_restore_selected_year_bucket_complement_lane_value_f32_text: state
.world_restore
.selected_year_bucket_complement_lane_value_f32_text
.clone(),
world_restore_selected_year_bucket_scaled_companion_lane_count: state
.world_restore
.selected_year_bucket_scaled_companion_lane_raw_u32
.len(),
world_restore_selected_year_bucket_scaled_companion_lane_value_f32_text: state
.world_restore
.selected_year_bucket_scaled_companion_lane_value_f32_text
.clone(),
world_restore_selected_year_gap_scalar_raw_u32: state
.world_restore
.selected_year_gap_scalar_raw_u32,
world_restore_selected_year_gap_scalar_value_f32_text: state
.world_restore
.selected_year_gap_scalar_value_f32_text
.clone(),
world_restore_absolute_counter_restore_kind: state
.world_restore
.absolute_counter_restore_kind
.clone(),
world_restore_absolute_counter_adjustment_context: state
.world_restore
.absolute_counter_adjustment_context
.clone(),
metadata_count: state.metadata.len(),
company_count: state.companies.len(),
active_company_count: state
.companies
.iter()
.filter(|company| company.active)
.count(),
company_market_state_owner_count: state.service_state.company_market_state.len(),
selected_company_outstanding_shares: selected_company_market_state
.map(|market_state| market_state.outstanding_shares),
selected_company_bond_count: selected_company_market_state
.map(|market_state| market_state.bond_count),
selected_company_largest_live_bond_principal: selected_company_market_state
.and_then(|market_state| market_state.largest_live_bond_principal),
selected_company_highest_coupon_live_bond_principal: selected_company_market_state
.and_then(|market_state| market_state.highest_coupon_live_bond_principal),
selected_company_assigned_share_pool: selected_company_annual_finance_state
.as_ref()
.map(|finance_state| finance_state.assigned_share_pool),
selected_company_unassigned_share_pool: state
.selected_company_id
.and_then(|company_id| runtime_company_unassigned_share_pool(state, company_id)),
selected_company_cached_share_price: selected_company_annual_finance_state
.as_ref()
.and_then(|finance_state| finance_state.cached_share_price),
selected_company_cached_share_price_value_f32_text: selected_company_market_state
.map(|market_state| raw_u32_to_f32_text(market_state.cached_share_price_raw_u32)),
selected_company_recent_per_share_cache_absolute_counter: selected_company_market_state
.map(|market_state| market_state.recent_per_share_cache_absolute_counter),
selected_company_recent_per_share_cached_value_f64_text: selected_company_market_state
.map(|market_state| {
raw_u64_to_f64_text(market_state.recent_per_share_cached_value_bits)
}),
selected_company_recent_per_share_subscore_value_f32_text:
selected_company_market_state.map(|market_state| {
raw_u32_to_f32_text(market_state.recent_per_share_subscore_raw_u32)
}),
selected_company_mutable_support_scalar_value_f32_text: selected_company_market_state
.map(|market_state| {
raw_u32_to_f32_text(market_state.mutable_support_scalar_raw_u32)
}),
selected_company_stat_band_root_0cfb_count: selected_company_market_state
.map(|market_state| market_state.stat_band_root_0cfb_candidates.len())
.unwrap_or(0),
selected_company_stat_band_root_0d7f_count: selected_company_market_state
.map(|market_state| market_state.stat_band_root_0d7f_candidates.len())
.unwrap_or(0),
selected_company_stat_band_root_1c47_count: selected_company_market_state
.map(|market_state| market_state.stat_band_root_1c47_candidates.len())
.unwrap_or(0),
selected_company_last_dividend_year: selected_company_market_state
.map(|market_state| market_state.last_dividend_year)
.filter(|year| *year != 0),
selected_company_years_since_founding: selected_company_annual_finance_state
.as_ref()
.and_then(|finance_state| finance_state.years_since_founding),
selected_company_years_since_last_bankruptcy: selected_company_annual_finance_state
.as_ref()
.and_then(|finance_state| finance_state.years_since_last_bankruptcy),
selected_company_years_since_last_dividend: selected_company_annual_finance_state
.as_ref()
.and_then(|finance_state| finance_state.years_since_last_dividend),
selected_company_current_partial_year_weight_numerator:
selected_company_annual_finance_state
.as_ref()
.and_then(|finance_state| finance_state.current_partial_year_weight_numerator),
selected_company_current_issue_absolute_counter: selected_company_annual_finance_state
.as_ref()
.and_then(|finance_state| finance_state.current_issue_absolute_counter),
selected_company_prior_issue_absolute_counter: selected_company_annual_finance_state
.as_ref()
.and_then(|finance_state| finance_state.prior_issue_absolute_counter),
selected_company_current_issue_age_absolute_counter_delta:
selected_company_annual_finance_state
.as_ref()
.and_then(|finance_state| {
finance_state.current_issue_age_absolute_counter_delta
}),
selected_company_periodic_side_latch_preferred_locomotive_engine_type_raw_u8:
selected_company_periodic_side_latch_state
.and_then(|latch_state| latch_state.preferred_locomotive_engine_type_raw_u8),
selected_company_periodic_side_latch_city_connection_latch:
selected_company_periodic_side_latch_state
.map(|latch_state| latch_state.city_connection_latch),
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
}),
active_periodic_route_preference_override_company_id: state
.service_state
.active_periodic_route_preference_override
.as_ref()
.map(|override_state| override_state.company_id),
active_periodic_route_preference_override_effective_raw_u8: state
.service_state
.active_periodic_route_preference_override
.as_ref()
.and_then(|override_state| override_state.effective_route_preference_raw_u8),
last_periodic_route_preference_override_company_id: state
.service_state
.last_periodic_route_preference_override
.as_ref()
.map(|override_state| override_state.company_id),
last_periodic_route_preference_override_effective_raw_u8: state
.service_state
.last_periodic_route_preference_override
.as_ref()
.and_then(|override_state| override_state.effective_route_preference_raw_u8),
selected_company_chairman_bonus_year: selected_company_market_state
.map(|market_state| market_state.chairman_bonus_year)
.filter(|year| *year != 0),
selected_company_chairman_bonus_amount: selected_company_market_state
.map(|market_state| market_state.chairman_bonus_amount)
.filter(|amount| *amount != 0),
selected_company_creditor_pressure_recent_bad_net_profit_year_count:
selected_company_creditor_pressure_state
.as_ref()
.map(|pressure_state| pressure_state.recent_bad_net_profit_year_count),
selected_company_creditor_pressure_recent_peak_revenue:
selected_company_creditor_pressure_state
.as_ref()
.and_then(|pressure_state| pressure_state.recent_peak_revenue),
selected_company_creditor_pressure_recent_three_year_net_profit_total:
selected_company_creditor_pressure_state
.as_ref()
.and_then(|pressure_state| pressure_state.recent_three_year_net_profit_total),
selected_company_creditor_pressure_cash_floor: selected_company_creditor_pressure_state
.as_ref()
.and_then(|pressure_state| pressure_state.pressure_ladder_cash_floor),
selected_company_creditor_pressure_cash_plus_slot_12_total:
selected_company_creditor_pressure_state
.as_ref()
.and_then(|pressure_state| pressure_state.current_cash_plus_slot_12_total),
selected_company_creditor_pressure_share_price_floor:
selected_company_creditor_pressure_state
.as_ref()
.and_then(|pressure_state| pressure_state.support_adjusted_share_price_floor),
selected_company_creditor_pressure_share_price_scalar:
selected_company_creditor_pressure_state
.as_ref()
.and_then(|pressure_state| pressure_state.support_adjusted_share_price_scalar),
selected_company_creditor_pressure_current_fuel_cost:
selected_company_creditor_pressure_state
.as_ref()
.and_then(|pressure_state| pressure_state.current_fuel_cost),
selected_company_creditor_pressure_current_fuel_cost_floor:
selected_company_creditor_pressure_state
.as_ref()
.and_then(|pressure_state| pressure_state.current_fuel_cost_floor),
selected_company_creditor_pressure_eligible_for_bankruptcy_branch:
selected_company_creditor_pressure_state
.as_ref()
.map(|pressure_state| pressure_state.eligible_for_bankruptcy_branch),
selected_company_deep_distress_current_cash: selected_company_deep_distress_state
.as_ref()
.and_then(|pressure_state| pressure_state.current_cash),
selected_company_deep_distress_recent_first_three_net_profit_years:
selected_company_deep_distress_state
.as_ref()
.map(|pressure_state| {
pressure_state.recent_first_three_net_profit_years.clone()
})
.unwrap_or_default(),
selected_company_deep_distress_cash_floor: selected_company_deep_distress_state
.as_ref()
.and_then(|pressure_state| pressure_state.deep_distress_cash_floor),
selected_company_deep_distress_net_profit_floor: selected_company_deep_distress_state
.as_ref()
.and_then(|pressure_state| pressure_state.deep_distress_net_profit_floor),
selected_company_deep_distress_eligible_for_bankruptcy_fallback:
selected_company_deep_distress_state
.as_ref()
.map(|pressure_state| pressure_state.eligible_for_bankruptcy_fallback),
selected_company_annual_bond_linked_transit_latch: selected_company_annual_bond_state
.as_ref()
.map(|bond_state| bond_state.linked_transit_latch),
selected_company_annual_bond_live_bond_count: selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.live_bond_count),
selected_company_annual_bond_live_bond_principal_total:
selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.live_bond_principal_total),
selected_company_annual_bond_matured_live_bond_count:
selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.matured_live_bond_count),
selected_company_annual_bond_matured_live_bond_principal_total:
selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.matured_live_bond_principal_total),
selected_company_annual_bond_next_live_bond_maturity_year:
selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.next_live_bond_maturity_year),
selected_company_annual_bond_live_bond_coupon_burden_total:
selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.live_bond_coupon_burden_total),
selected_company_annual_bond_current_cash: selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.current_cash),
selected_company_annual_bond_cash_after_full_repayment:
selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.cash_after_full_repayment),
selected_company_annual_bond_issue_cash_floor: selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.issue_cash_floor),
selected_company_annual_bond_issue_principal_step: selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.issue_principal_step),
selected_company_annual_bond_proposed_issue_bond_count:
selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.proposed_issue_bond_count),
selected_company_annual_bond_proposed_issue_total_principal:
selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.proposed_issue_total_principal),
selected_company_annual_bond_proposed_issue_years_to_maturity:
selected_company_annual_bond_state
.as_ref()
.and_then(|bond_state| bond_state.proposed_issue_years_to_maturity),
selected_company_annual_bond_eligible_for_issue_branch:
selected_company_annual_bond_state
.as_ref()
.map(|bond_state| bond_state.eligible_for_bond_issue_branch),
selected_company_stock_repurchase_city_connection_latch:
selected_company_stock_repurchase_state
.as_ref()
.map(|repurchase_state| repurchase_state.city_connection_latch),
selected_company_stock_repurchase_building_density_growth_setting:
selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| repurchase_state.building_density_growth_setting),
selected_company_stock_repurchase_linked_chairman_profile_id:
selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| repurchase_state.linked_chairman_profile_id),
selected_company_stock_repurchase_linked_chairman_personality_raw_u8:
selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| {
repurchase_state.linked_chairman_personality_raw_u8
}),
selected_company_stock_repurchase_batch_size: selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| repurchase_state.repurchase_batch_size),
selected_company_stock_repurchase_factor_basis_points:
selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| repurchase_state.repurchase_factor_basis_points),
selected_company_stock_repurchase_current_cash: selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| repurchase_state.current_cash),
selected_company_stock_repurchase_stock_value_gate_cash_floor:
selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| repurchase_state.stock_value_gate_cash_floor),
selected_company_stock_repurchase_support_adjusted_share_price_scalar:
selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| {
repurchase_state.support_adjusted_share_price_scalar
}),
selected_company_stock_repurchase_affordability_cash_floor:
selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| repurchase_state.affordability_cash_floor),
selected_company_stock_repurchase_unassigned_share_pool:
selected_company_stock_repurchase_state
.as_ref()
.and_then(|repurchase_state| repurchase_state.unassigned_share_pool),
selected_company_stock_repurchase_eligible_for_single_batch:
selected_company_stock_repurchase_state
.as_ref()
.map(|repurchase_state| repurchase_state.eligible_for_single_batch_repurchase),
selected_company_stock_issue_live_bond_count: selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.live_bond_count),
selected_company_stock_issue_initial_batch_size: selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.initial_issue_batch_size),
selected_company_stock_issue_trimmed_batch_size: selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.trimmed_issue_batch_size),
selected_company_stock_issue_share_pressure_basis_points:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.share_pressure_basis_points),
selected_company_stock_issue_pressured_share_price_scalar:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| {
issue_state.pressured_support_adjusted_share_price_scalar
}),
selected_company_stock_issue_pressured_proceeds: selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.pressured_proceeds),
selected_company_stock_issue_book_value_per_share_floor_applied:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.book_value_per_share_floor_applied),
selected_company_stock_issue_price_to_book_ratio_basis_points:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.price_to_book_ratio_basis_points),
selected_company_stock_issue_current_cash: selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.current_cash),
selected_company_stock_issue_highest_coupon_live_bond_principal:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.highest_coupon_live_bond_principal),
selected_company_stock_issue_highest_coupon_live_bond_rate_basis_points:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.highest_coupon_live_bond_rate_basis_points),
selected_company_stock_issue_current_issue_age_absolute_counter_delta:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.current_issue_age_absolute_counter_delta),
selected_company_stock_issue_current_issue_cooldown_floor:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.current_issue_cooldown_floor),
selected_company_stock_issue_minimum_price_to_book_ratio_basis_points:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.minimum_price_to_book_ratio_basis_points),
selected_company_stock_issue_passes_share_price_floor:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.passes_share_price_floor),
selected_company_stock_issue_passes_proceeds_floor: selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.passes_proceeds_floor),
selected_company_stock_issue_passes_cash_gate: selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.passes_cash_gate),
selected_company_stock_issue_passes_issue_cooldown_gate:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.passes_issue_cooldown_gate),
selected_company_stock_issue_passes_coupon_price_to_book_gate:
selected_company_stock_issue_state
.as_ref()
.and_then(|issue_state| issue_state.passes_coupon_price_to_book_gate),
selected_company_stock_issue_eligible_for_double_tranche:
selected_company_stock_issue_state
.as_ref()
.map(|issue_state| issue_state.eligible_for_double_tranche_issue),
selected_company_dividend_weighted_recent_net_profit_total:
selected_company_dividend_state
.as_ref()
.and_then(|dividend_state| dividend_state.weighted_recent_net_profit_total),
selected_company_dividend_weighted_recent_net_profit_average:
selected_company_dividend_state
.as_ref()
.and_then(|dividend_state| dividend_state.weighted_recent_net_profit_average),
selected_company_dividend_current_cash: selected_company_dividend_state
.as_ref()
.and_then(|dividend_state| dividend_state.current_cash),
selected_company_dividend_tiny_unassigned_share_cash_supplement_branch:
selected_company_dividend_state
.as_ref()
.map(|dividend_state| {
dividend_state.tiny_unassigned_share_cash_supplement_branch
}),
selected_company_dividend_tentative_target_per_share_tenths:
selected_company_dividend_state
.as_ref()
.and_then(|dividend_state| {
dividend_state.tentative_target_dividend_per_share_tenths
}),
selected_company_dividend_current_per_share_tenths: selected_company_dividend_state
.as_ref()
.and_then(|dividend_state| dividend_state.current_dividend_per_share_tenths),
selected_company_dividend_growth_adjusted_current_per_share_tenths:
selected_company_dividend_state
.as_ref()
.and_then(|dividend_state| {
dividend_state.growth_adjusted_current_dividend_per_share_tenths
}),
selected_company_dividend_board_approved_ceiling_tenths:
selected_company_dividend_state
.as_ref()
.and_then(|dividend_state| {
dividend_state.board_approved_dividend_rate_ceiling_tenths
}),
selected_company_dividend_proposed_per_share_tenths: selected_company_dividend_state
.as_ref()
.and_then(|dividend_state| dividend_state.proposed_dividend_per_share_tenths),
selected_company_dividend_eligible_for_adjustment_branch:
selected_company_dividend_state
.as_ref()
.map(|dividend_state| dividend_state.eligible_for_dividend_adjustment_branch),
selected_company_annual_finance_policy_action:
selected_company_annual_finance_policy_state
.as_ref()
.map(|policy_state| {
runtime_company_annual_finance_policy_action_label(policy_state.action)
.to_string()
}),
selected_company_annual_finance_news_family_candidate: state
.selected_company_id
.and_then(|company_id| {
state
.service_state
.annual_finance_last_news_family_candidates
.get(&company_id)
})
.cloned(),
selected_company_annual_finance_last_news_selector: state
.selected_company_id
.and_then(|company_id| {
state
.service_state
.annual_finance_last_news_events
.iter()
.rev()
.find(|news| news.company_id == company_id)
})
.map(|news| news.selector_label.clone()),
annual_finance_last_news_event_count: state
.service_state
.annual_finance_last_news_events
.len(),
selected_company_annual_finance_policy_creditor_pressure_bankruptcy_eligible:
selected_company_annual_finance_policy_state
.as_ref()
.map(|policy_state| policy_state.creditor_pressure_bankruptcy_eligible),
selected_company_annual_finance_policy_deep_distress_bankruptcy_fallback_eligible:
selected_company_annual_finance_policy_state
.as_ref()
.map(|policy_state| policy_state.deep_distress_bankruptcy_fallback_eligible),
selected_company_annual_finance_policy_bond_issue_eligible:
selected_company_annual_finance_policy_state
.as_ref()
.map(|policy_state| policy_state.bond_issue_eligible),
selected_company_annual_finance_policy_stock_repurchase_eligible:
selected_company_annual_finance_policy_state
.as_ref()
.map(|policy_state| policy_state.stock_repurchase_eligible),
selected_company_annual_finance_policy_stock_issue_eligible:
selected_company_annual_finance_policy_state
.as_ref()
.map(|policy_state| policy_state.stock_issue_eligible),
selected_company_annual_finance_policy_dividend_adjustment_eligible:
selected_company_annual_finance_policy_state
.as_ref()
.map(|policy_state| policy_state.dividend_adjustment_eligible),
player_count: state.players.len(),
chairman_profile_count: state.chairman_profiles.len(),
active_chairman_profile_count: state
.chairman_profiles
.iter()
.filter(|profile| profile.active)
.count(),
selected_chairman_profile_id: state.selected_chairman_profile_id,
linked_chairman_company_count: state
.companies
.iter()
.filter(|company| company.linked_chairman_profile_id.is_some())
.count(),
company_takeover_cooldown_count: state
.companies
.iter()
.filter(|company| company.takeover_cooldown_year.is_some())
.count(),
company_merger_cooldown_count: state
.companies
.iter()
.filter(|company| company.merger_cooldown_year.is_some())
.count(),
train_count: state.trains.len(),
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(),
packed_event_record_count: state
.packed_event_collection
.as_ref()
.map(|summary| summary.live_record_count)
.unwrap_or(0),
packed_event_decoded_record_count: state
.packed_event_collection
.as_ref()
.map(|summary| summary.decoded_record_count)
.unwrap_or(0),
packed_event_imported_runtime_record_count: state
.packed_event_collection
.as_ref()
.map(|summary| summary.imported_runtime_record_count)
.unwrap_or(0),
packed_event_parity_only_record_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| record.decode_status == "parity_only")
.count()
})
.unwrap_or(0),
packed_event_unsupported_record_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| record.decode_status == "unsupported_framing")
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_company_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_company_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_selection_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_selection_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_company_role_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_company_role_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_player_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_player_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_player_selection_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_player_selection_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_player_role_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_player_role_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_chairman_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_chairman_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_chairman_target_scope_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_chairman_target_scope")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_condition_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_condition_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_player_condition_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_player_condition_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_company_condition_scope_disabled_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_company_condition_scope_disabled")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_player_condition_scope_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_player_condition_scope")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_territory_condition_scope_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_territory_condition_scope")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_territory_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_territory_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_named_territory_binding_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_named_territory_binding")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_unmapped_ordinary_condition_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_unmapped_ordinary_condition")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_unmapped_world_condition_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_unmapped_world_condition")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_compact_control_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_compact_control")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_shell_owned_descriptor_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_shell_owned_descriptor")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_evidence_blocked_descriptor_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_evidence_blocked_descriptor")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_variant_or_scope_blocked_descriptor_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_variant_or_scope_blocked_descriptor")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_unmapped_real_descriptor_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_unmapped_real_descriptor")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_unmapped_world_descriptor_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_unmapped_world_descriptor")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_territory_access_variant_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_territory_access_variant")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_territory_access_scope_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_territory_access_scope")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_train_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_train_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_train_territory_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_train_territory_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_missing_locomotive_catalog_context_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref()
== Some("blocked_missing_locomotive_catalog_context")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_confiscation_variant_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref() == Some("blocked_confiscation_variant")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_retire_train_variant_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref() == Some("blocked_retire_train_variant")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_retire_train_scope_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref() == Some("blocked_retire_train_scope")
})
.count()
})
.unwrap_or(0),
packed_event_blocked_structural_only_count: state
.packed_event_collection
.as_ref()
.map(|summary| {
summary
.records
.iter()
.filter(|record| {
record.import_outcome.as_deref() == Some("blocked_structural_only")
})
.count()
})
.unwrap_or(0),
event_runtime_record_count: state.event_runtime_records.len(),
candidate_availability_count: state.candidate_availability.len(),
zero_candidate_availability_count: state
.candidate_availability
.values()
.filter(|value| **value == 0)
.count(),
named_locomotive_availability_count: state.named_locomotive_availability.len(),
zero_named_locomotive_availability_count: state
.named_locomotive_availability
.values()
.filter(|value| **value == 0)
.count(),
named_locomotive_cost_count: state.named_locomotive_cost.len(),
cargo_production_override_count: state.cargo_production_overrides.len(),
world_runtime_variable_count: state.world_runtime_variables.len(),
company_runtime_variable_owner_count: state.company_runtime_variables.len(),
player_runtime_variable_owner_count: state.player_runtime_variables.len(),
territory_runtime_variable_owner_count: state.territory_runtime_variables.len(),
world_scalar_override_count: state.world_scalar_overrides.len(),
special_condition_count: state.special_conditions.len(),
enabled_special_condition_count: state
.special_conditions
.values()
.filter(|value| **value != 0)
.count(),
save_profile_kind: state.save_profile.profile_kind.clone(),
save_profile_family: state.save_profile.profile_family.clone(),
save_profile_map_path: state.save_profile.map_path.clone(),
save_profile_display_name: state.save_profile.display_name.clone(),
save_profile_selected_year_profile_lane: state.save_profile.selected_year_profile_lane,
save_profile_sandbox_enabled: state.save_profile.sandbox_enabled,
save_profile_campaign_scenario_enabled: state.save_profile.campaign_scenario_enabled,
save_profile_staged_profile_copy_on_restore: state
.save_profile
.staged_profile_copy_on_restore,
total_event_record_service_count: state.service_state.total_event_record_services,
periodic_boundary_call_count: state.service_state.periodic_boundary_calls,
annual_finance_service_call_count: state.service_state.annual_finance_service_calls,
periodic_route_preference_override_apply_count: state
.service_state
.periodic_route_preference_override_apply_count,
periodic_route_preference_override_restore_count: state
.service_state
.periodic_route_preference_override_restore_count,
annual_dividend_adjustment_commit_count: state
.service_state
.annual_dividend_adjustment_commit_count,
annual_bond_last_retired_principal_total: state
.service_state
.annual_bond_last_retired_principal_total,
annual_bond_last_issued_principal_total: state
.service_state
.annual_bond_last_issued_principal_total,
annual_bond_last_principal_flow_relation:
runtime_annual_bond_principal_flow_relation_label(
state.service_state.annual_bond_last_retired_principal_total,
state.service_state.annual_bond_last_issued_principal_total,
)
.map(str::to_string),
annual_stock_repurchase_last_share_count: state
.service_state
.annual_stock_repurchase_last_share_count,
annual_stock_issue_last_share_count: state
.service_state
.annual_stock_issue_last_share_count,
total_trigger_dispatch_count: state
.service_state
.trigger_dispatch_counts
.values()
.sum(),
dirty_rerun_count: state.service_state.dirty_rerun_count,
total_company_cash: state
.companies
.iter()
.map(|company| company.current_cash)
.sum(),
}
}
}
#[cfg(test)]
mod tests {
use std::collections::BTreeMap;
use crate::{
CalendarPoint, RuntimeCompany, RuntimeCompanyControllerKind,
RuntimePackedEventCollectionSummary, RuntimePackedEventRecordSummary, RuntimePlayer,
RuntimeSaveProfileState, RuntimeServiceState, RuntimeState, RuntimeTerritory,
RuntimeTrackPieceCounts, RuntimeWorldRestoreState,
};
use super::RuntimeSummary;
#[test]
fn counts_structural_only_and_missing_context_frontiers() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
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(2),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
players: Vec::new(),
selected_player_id: None,
chairman_profiles: vec![crate::RuntimeChairmanProfile {
profile_id: 1,
name: "Chairman One".to_string(),
active: true,
current_cash: 0,
linked_company_id: Some(1),
company_holdings: std::collections::BTreeMap::from([(1, 5_000)]),
holdings_value_total: 0,
net_worth_total: 0,
purchasing_power_total: 0,
}],
selected_chairman_profile_id: Some(1),
trains: Vec::new(),
locomotive_catalog: vec![
crate::RuntimeLocomotiveCatalogEntry {
locomotive_id: 10,
name: "Big Boy 4-8-8-4".to_string(),
},
crate::RuntimeLocomotiveCatalogEntry {
locomotive_id: 58,
name: "VL80T".to_string(),
},
],
cargo_catalog: Vec::new(),
territories: Vec::new(),
company_territory_track_piece_counts: Vec::new(),
company_territory_access: Vec::new(),
packed_event_collection: Some(RuntimePackedEventCollectionSummary {
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()),
packed_state_version: 0x3e9,
packed_state_version_hex: "0x000003e9".to_string(),
live_id_bound: 11,
live_record_count: 5,
live_entry_ids: vec![3, 7, 9, 10, 11],
decoded_record_count: 5,
imported_runtime_record_count: 0,
records: vec![
RuntimePackedEventRecordSummary {
record_index: 0,
live_entry_id: 3,
payload_offset: Some(0x7202),
payload_len: Some(96),
decode_status: "parity_only".to_string(),
payload_family: "real_packed_v1".to_string(),
trigger_kind: None,
active: None,
marks_collection_dirty: None,
one_shot: None,
compact_control: None,
text_bands: Vec::new(),
standalone_condition_row_count: 0,
standalone_condition_rows: Vec::new(),
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![0, 0, 0, 0],
grouped_effect_rows: Vec::new(),
grouped_company_targets: Vec::new(),
decoded_conditions: Vec::new(),
decoded_actions: Vec::new(),
executable_import_ready: false,
import_outcome: Some("blocked_missing_compact_control".to_string()),
notes: Vec::new(),
},
RuntimePackedEventRecordSummary {
record_index: 1,
live_entry_id: 7,
payload_offset: Some(0x7262),
payload_len: Some(48),
decode_status: "parity_only".to_string(),
payload_family: "synthetic_harness".to_string(),
trigger_kind: Some(7),
active: Some(true),
marks_collection_dirty: Some(false),
one_shot: Some(false),
compact_control: None,
text_bands: Vec::new(),
standalone_condition_row_count: 0,
standalone_condition_rows: Vec::new(),
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![0, 0, 0, 0],
grouped_effect_rows: Vec::new(),
grouped_company_targets: Vec::new(),
decoded_conditions: Vec::new(),
decoded_actions: Vec::new(),
executable_import_ready: false,
import_outcome: Some("blocked_missing_company_context".to_string()),
notes: Vec::new(),
},
RuntimePackedEventRecordSummary {
record_index: 2,
live_entry_id: 9,
payload_offset: Some(0x7292),
payload_len: Some(48),
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: None,
compact_control: None,
text_bands: Vec::new(),
standalone_condition_row_count: 0,
standalone_condition_rows: Vec::new(),
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![0, 0, 0, 0],
grouped_effect_rows: Vec::new(),
grouped_company_targets: Vec::new(),
decoded_conditions: Vec::new(),
decoded_actions: Vec::new(),
executable_import_ready: false,
import_outcome: Some(
"blocked_company_condition_scope_disabled".to_string(),
),
notes: Vec::new(),
},
RuntimePackedEventRecordSummary {
record_index: 3,
live_entry_id: 10,
payload_offset: Some(0x72c2),
payload_len: Some(48),
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: None,
compact_control: None,
text_bands: Vec::new(),
standalone_condition_row_count: 0,
standalone_condition_rows: Vec::new(),
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![0, 0, 0, 0],
grouped_effect_rows: Vec::new(),
grouped_company_targets: Vec::new(),
decoded_conditions: Vec::new(),
decoded_actions: Vec::new(),
executable_import_ready: false,
import_outcome: Some("blocked_player_condition_scope".to_string()),
notes: Vec::new(),
},
RuntimePackedEventRecordSummary {
record_index: 4,
live_entry_id: 11,
payload_offset: Some(0x72f2),
payload_len: Some(48),
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: None,
compact_control: None,
text_bands: Vec::new(),
standalone_condition_row_count: 0,
standalone_condition_rows: Vec::new(),
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![0, 0, 0, 0],
grouped_effect_rows: Vec::new(),
grouped_company_targets: Vec::new(),
decoded_conditions: Vec::new(),
decoded_actions: Vec::new(),
executable_import_ready: false,
import_outcome: Some("blocked_territory_condition_scope".to_string()),
notes: Vec::new(),
},
],
}),
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::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(
summary.packed_event_blocked_missing_compact_control_count,
1
);
assert_eq!(
summary.packed_event_blocked_unmapped_real_descriptor_count,
0
);
assert_eq!(summary.packed_event_blocked_structural_only_count, 0);
assert_eq!(
summary.packed_event_blocked_missing_company_context_count,
1
);
assert_eq!(
summary.packed_event_blocked_missing_selection_context_count,
0
);
assert_eq!(
summary.packed_event_blocked_missing_company_role_context_count,
0
);
assert_eq!(
summary.packed_event_blocked_missing_condition_context_count,
0
);
assert_eq!(
summary.packed_event_blocked_company_condition_scope_disabled_count,
1
);
assert_eq!(summary.packed_event_blocked_player_condition_scope_count, 1);
assert_eq!(
summary.packed_event_blocked_territory_condition_scope_count,
1
);
}
#[test]
fn summarizes_save_world_issue_and_economic_tuning_restore_state() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState {
packed_year_word_raw_u16: Some(0x0201),
partial_year_progress_raw_u8: Some(3),
current_calendar_tuple_word_raw_u32: Some(0x0108_0210),
current_calendar_tuple_word_2_raw_u32: Some(0x35e6_3160),
absolute_counter_raw_u32: Some(5),
absolute_counter_mirror_raw_u32: Some(5),
issue_37_value: Some(3),
issue_38_value: Some(1),
issue_39_value: Some(2),
issue_3a_value: Some(4),
issue_37_multiplier_raw_u32: Some(0x3d75c28f),
issue_37_multiplier_value_f32_text: Some("0.06".to_string()),
stock_issue_and_buyback_policy_raw_u8: Some(0),
bond_issue_and_repayment_policy_raw_u8: Some(1),
bankruptcy_policy_raw_u8: Some(0),
dividend_policy_raw_u8: Some(1),
stock_issue_and_buyback_allowed: Some(true),
bond_issue_and_repayment_allowed: Some(false),
bankruptcy_allowed: Some(true),
dividend_adjustment_allowed: Some(false),
economic_tuning_mirror_raw_u32: Some(0x3f46dff5),
economic_tuning_mirror_value_f32_text: Some("0.7766201".to_string()),
economic_tuning_lane_raw_u32: vec![
0x3f400000, 0x3be56042, 0x3c03126f, 0x3c1374bc, 0x3c23d70a, 0x3c23d70a,
],
economic_tuning_lane_value_f32_text: vec![
"0.75".to_string(),
"0.007".to_string(),
"0.008".to_string(),
"0.009".to_string(),
"0.01".to_string(),
"0.01".to_string(),
],
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),
all_diesel_locomotives_available_enabled: Some(false),
all_electric_locomotives_available_raw_u8: Some(1),
all_electric_locomotives_available_enabled: Some(true),
cached_available_locomotive_rating_raw_u32: Some(0x41a00000),
cached_available_locomotive_rating_value_f32_text: Some("20.000000".to_string()),
selected_year_bucket_scalar_raw_u32: Some(25.0f32.to_bits()),
selected_year_bucket_scalar_value_f32_text: Some("25.000000".to_string()),
selected_year_bucket_direct_lane_raw_u32: vec![
22.5f32.to_bits(),
26.25f32.to_bits(),
17.5f32.to_bits(),
],
selected_year_bucket_direct_lane_value_f32_text: vec![
"22.500000".to_string(),
"26.250000".to_string(),
"17.500000".to_string(),
],
selected_year_bucket_complement_lane_raw_u32: vec![
0.999121f32.to_bits(),
0.998998f32.to_bits(),
0.999210f32.to_bits(),
],
selected_year_bucket_complement_lane_value_f32_text: vec![
"0.999121".to_string(),
"0.998998".to_string(),
"0.999210".to_string(),
],
selected_year_bucket_scaled_companion_lane_raw_u32: vec![
139.16667f32.to_bits(),
122.5f32.to_bits(),
171.42857f32.to_bits(),
],
selected_year_bucket_scaled_companion_lane_value_f32_text: vec![
"139.166672".to_string(),
"122.500000".to_string(),
"171.428574".to_string(),
],
selected_year_gap_scalar_raw_u32: Some(0x3eaaaaab),
selected_year_gap_scalar_value_f32_text: Some("0.333333".to_string()),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
players: Vec::new(),
selected_player_id: None,
chairman_profiles: vec![crate::RuntimeChairmanProfile {
profile_id: 1,
name: "Chairman One".to_string(),
active: true,
current_cash: 0,
linked_company_id: Some(1),
company_holdings: std::collections::BTreeMap::from([(1, 5_000)]),
holdings_value_total: 0,
net_worth_total: 0,
purchasing_power_total: 0,
}],
selected_chairman_profile_id: Some(1),
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(),
cargo_production_overrides: BTreeMap::new(),
named_cargo_price_overrides: BTreeMap::new(),
all_cargo_price_override: None,
named_cargo_production_overrides: BTreeMap::new(),
all_cargo_production_override: None,
factory_cargo_production_override: None,
farm_mine_cargo_production_override: None,
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::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(summary.world_restore_packed_year_word_raw_u16, Some(0x0201));
assert_eq!(summary.world_restore_partial_year_progress_raw_u8, Some(3));
assert_eq!(
summary.world_restore_current_calendar_tuple_word_raw_u32,
Some(0x0108_0210)
);
assert_eq!(
summary.world_restore_current_calendar_tuple_word_2_raw_u32,
Some(0x35e6_3160)
);
assert_eq!(summary.world_restore_absolute_counter_raw_u32, Some(5));
assert_eq!(
summary.world_restore_absolute_counter_mirror_raw_u32,
Some(5)
);
assert_eq!(summary.world_restore_issue_37_value, Some(3));
assert_eq!(summary.world_restore_issue_38_value, Some(1));
assert_eq!(summary.world_restore_issue_39_value, Some(2));
assert_eq!(summary.world_restore_issue_3a_value, Some(4));
assert_eq!(
summary.world_restore_issue_37_multiplier_raw_u32,
Some(0x3d75c28f)
);
assert_eq!(
summary.world_restore_stock_issue_and_buyback_policy_raw_u8,
Some(0)
);
assert_eq!(
summary.world_restore_bond_issue_and_repayment_policy_raw_u8,
Some(1)
);
assert_eq!(summary.world_restore_bankruptcy_policy_raw_u8, Some(0));
assert_eq!(summary.world_restore_dividend_policy_raw_u8, Some(1));
assert_eq!(
summary.world_restore_stock_issue_and_buyback_allowed,
Some(true)
);
assert_eq!(
summary.world_restore_bond_issue_and_repayment_allowed,
Some(false)
);
assert_eq!(summary.world_restore_bankruptcy_allowed, Some(true));
assert_eq!(
summary.world_restore_dividend_adjustment_allowed,
Some(false)
);
assert_eq!(
summary
.world_restore_issue_37_multiplier_value_f32_text
.as_deref(),
Some("0.06")
);
assert_eq!(
summary.world_restore_economic_tuning_mirror_raw_u32,
Some(0x3f46dff5)
);
assert_eq!(
summary
.world_restore_economic_tuning_mirror_value_f32_text
.as_deref(),
Some("0.7766201")
);
assert_eq!(
summary.world_restore_linked_site_removal_follow_on_gate_raw_u8,
Some(1)
);
assert_eq!(
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)
);
assert_eq!(
summary.world_restore_all_steam_locomotives_available_enabled,
Some(true)
);
assert_eq!(
summary.world_restore_all_diesel_locomotives_available_raw_u8,
Some(0)
);
assert_eq!(
summary.world_restore_all_diesel_locomotives_available_enabled,
Some(false)
);
assert_eq!(
summary.world_restore_all_electric_locomotives_available_raw_u8,
Some(1)
);
assert_eq!(
summary.world_restore_all_electric_locomotives_available_enabled,
Some(true)
);
assert_eq!(
summary.world_restore_cached_available_locomotive_rating_raw_u32,
Some(0x41a00000)
);
assert_eq!(
summary
.world_restore_cached_available_locomotive_rating_value_f32_text
.as_deref(),
Some("20.000000")
);
assert_eq!(
summary.world_restore_selected_year_bucket_scalar_raw_u32,
Some(25.0f32.to_bits())
);
assert_eq!(
summary
.world_restore_selected_year_bucket_scalar_value_f32_text
.as_deref(),
Some("25.000000")
);
assert_eq!(
summary.world_restore_selected_year_bucket_direct_lane_count,
3
);
assert_eq!(
summary.world_restore_selected_year_bucket_direct_lane_value_f32_text,
vec!["22.500000", "26.250000", "17.500000"]
);
assert_eq!(
summary.world_restore_selected_year_bucket_complement_lane_count,
3
);
assert_eq!(
summary.world_restore_selected_year_bucket_complement_lane_value_f32_text,
vec!["0.999121", "0.998998", "0.999210"]
);
assert_eq!(
summary.world_restore_selected_year_bucket_scaled_companion_lane_count,
3
);
assert_eq!(
summary.world_restore_selected_year_bucket_scaled_companion_lane_value_f32_text,
vec!["139.166672", "122.500000", "171.428574"]
);
assert_eq!(summary.world_restore_economic_tuning_lane_count, 6);
assert_eq!(
summary.world_restore_economic_tuning_lane_value_f32_text,
vec!["0.75", "0.007", "0.008", "0.009", "0.01", "0.01"]
);
assert_eq!(
summary.world_restore_selected_year_gap_scalar_raw_u32,
Some(0x3eaaaaab)
);
assert_eq!(
summary
.world_restore_selected_year_gap_scalar_value_f32_text
.as_deref(),
Some("0.333333")
);
}
#[test]
fn counts_active_companies_separately_from_total_companies() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
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(2),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![
RuntimeCompany {
company_id: 1,
current_cash: 10,
debt: 0,
credit_rating_score: None,
prime_rate: None,
track_piece_counts: RuntimeTrackPieceCounts::default(),
active: true,
available_track_laying_capacity: None,
linked_chairman_profile_id: None,
book_value_per_share: 0,
investor_confidence: 0,
management_attitude: 0,
takeover_cooldown_year: None,
merger_cooldown_year: None,
controller_kind: RuntimeCompanyControllerKind::Human,
},
RuntimeCompany {
company_id: 2,
current_cash: 20,
debt: 0,
credit_rating_score: None,
prime_rate: None,
track_piece_counts: RuntimeTrackPieceCounts::default(),
active: false,
available_track_laying_capacity: Some(7),
linked_chairman_profile_id: None,
book_value_per_share: 0,
investor_confidence: 0,
management_attitude: 0,
takeover_cooldown_year: None,
merger_cooldown_year: None,
controller_kind: RuntimeCompanyControllerKind::Ai,
},
],
selected_company_id: None,
players: Vec::new(),
selected_player_id: None,
chairman_profiles: vec![crate::RuntimeChairmanProfile {
profile_id: 1,
name: "Chairman One".to_string(),
active: true,
current_cash: 0,
linked_company_id: Some(1),
company_holdings: std::collections::BTreeMap::from([(1, 5_000)]),
holdings_value_total: 0,
net_worth_total: 0,
purchasing_power_total: 0,
}],
selected_chairman_profile_id: Some(1),
trains: Vec::new(),
locomotive_catalog: vec![
crate::RuntimeLocomotiveCatalogEntry {
locomotive_id: 10,
name: "Big Boy 4-8-8-4".to_string(),
},
crate::RuntimeLocomotiveCatalogEntry {
locomotive_id: 58,
name: "VL80T".to_string(),
},
],
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::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(summary.company_count, 2);
assert_eq!(summary.active_company_count, 1);
}
#[test]
fn counts_named_locomotive_availability_entries_and_zero_values() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
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(2),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
players: Vec::new(),
selected_player_id: None,
chairman_profiles: Vec::new(),
selected_chairman_profile_id: None,
trains: Vec::new(),
locomotive_catalog: vec![
crate::RuntimeLocomotiveCatalogEntry {
locomotive_id: 10,
name: "Big Boy 4-8-8-4".to_string(),
},
crate::RuntimeLocomotiveCatalogEntry {
locomotive_id: 58,
name: "VL80T".to_string(),
},
],
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::from([
("Big Boy".to_string(), 0),
("GP7".to_string(), 1),
("Mikado".to_string(), 0),
]),
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::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(summary.locomotive_catalog_count, 2);
assert_eq!(summary.named_locomotive_availability_count, 3);
assert_eq!(summary.zero_named_locomotive_availability_count, 2);
assert_eq!(summary.named_locomotive_cost_count, 0);
}
#[test]
fn counts_named_locomotive_cost_entries() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState::default(),
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
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::from([
("Big Boy".to_string(), 250000),
("GP7".to_string(), 175000),
]),
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::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(summary.named_locomotive_cost_count, 2);
}
#[test]
fn counts_world_scalar_override_surfaces() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState {
territory_access_cost: Some(750000),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
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::from([(1, 125), (2, 250)]),
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::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(summary.cargo_production_override_count, 2);
assert_eq!(summary.world_restore_territory_access_cost, Some(750000));
}
#[test]
fn counts_runtime_variable_surfaces() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState::default(),
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 1,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: RuntimeCompanyControllerKind::Human,
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: None,
players: vec![RuntimePlayer {
player_id: 2,
current_cash: 0,
active: true,
controller_kind: RuntimeCompanyControllerKind::Human,
}],
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![RuntimeTerritory {
territory_id: 3,
name: Some("East".to_string()),
track_piece_counts: RuntimeTrackPieceCounts::default(),
}],
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::from([(1, 9)]),
company_runtime_variables: BTreeMap::from([(1, BTreeMap::from([(2, 11)]))]),
player_runtime_variables: BTreeMap::from([(2, BTreeMap::from([(3, 13)]))]),
territory_runtime_variables: BTreeMap::from([(3, BTreeMap::from([(4, 15)]))]),
world_scalar_overrides: BTreeMap::new(),
special_conditions: BTreeMap::new(),
service_state: RuntimeServiceState::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(summary.world_runtime_variable_count, 1);
assert_eq!(summary.company_runtime_variable_owner_count, 1);
assert_eq!(summary.player_runtime_variable_owner_count, 1);
assert_eq!(summary.territory_runtime_variable_owner_count, 1);
}
#[test]
fn counts_world_frontier_buckets_separately() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState::default(),
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
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: Some(RuntimePackedEventCollectionSummary {
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()),
packed_state_version: 0x3e9,
packed_state_version_hex: "0x000003e9".to_string(),
live_id_bound: 2,
live_record_count: 2,
live_entry_ids: vec![21, 22],
decoded_record_count: 2,
imported_runtime_record_count: 0,
records: vec![
RuntimePackedEventRecordSummary {
record_index: 0,
live_entry_id: 21,
payload_offset: Some(0x7202),
payload_len: Some(96),
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: None,
compact_control: None,
text_bands: Vec::new(),
standalone_condition_row_count: 0,
standalone_condition_rows: Vec::new(),
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![1, 0, 0, 0],
grouped_effect_rows: Vec::new(),
grouped_company_targets: Vec::new(),
decoded_conditions: Vec::new(),
decoded_actions: Vec::new(),
executable_import_ready: false,
import_outcome: Some("blocked_unmapped_world_descriptor".to_string()),
notes: Vec::new(),
},
RuntimePackedEventRecordSummary {
record_index: 1,
live_entry_id: 22,
payload_offset: Some(0x7242),
payload_len: Some(96),
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: None,
compact_control: None,
text_bands: Vec::new(),
standalone_condition_row_count: 1,
standalone_condition_rows: Vec::new(),
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![0, 0, 0, 0],
grouped_effect_rows: Vec::new(),
grouped_company_targets: Vec::new(),
decoded_conditions: Vec::new(),
decoded_actions: Vec::new(),
executable_import_ready: false,
import_outcome: Some("blocked_unmapped_world_condition".to_string()),
notes: Vec::new(),
},
],
}),
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::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(
summary.packed_event_blocked_unmapped_world_descriptor_count,
1
);
assert_eq!(
summary.packed_event_blocked_unmapped_world_condition_count,
1
);
}
#[test]
fn counts_missing_locomotive_catalog_context_frontier() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState::default(),
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
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: Some(RuntimePackedEventCollectionSummary {
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()),
packed_state_version: 0x3e9,
packed_state_version_hex: "0x000003e9".to_string(),
live_id_bound: 1,
live_record_count: 1,
live_entry_ids: vec![1],
decoded_record_count: 1,
imported_runtime_record_count: 0,
records: vec![RuntimePackedEventRecordSummary {
record_index: 0,
live_entry_id: 1,
payload_offset: Some(0x7202),
payload_len: Some(96),
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: None,
compact_control: None,
text_bands: Vec::new(),
standalone_condition_row_count: 0,
standalone_condition_rows: Vec::new(),
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![1, 0, 0, 0],
grouped_effect_rows: Vec::new(),
grouped_company_targets: Vec::new(),
decoded_conditions: Vec::new(),
decoded_actions: Vec::new(),
executable_import_ready: false,
import_outcome: Some("blocked_missing_locomotive_catalog_context".to_string()),
notes: Vec::new(),
}],
}),
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::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(
summary.packed_event_blocked_missing_locomotive_catalog_context_count,
1
);
}
#[test]
fn counts_shell_owned_descriptor_frontier() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: RuntimeSaveProfileState::default(),
world_restore: RuntimeWorldRestoreState::default(),
metadata: BTreeMap::new(),
companies: Vec::new(),
selected_company_id: None,
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: Some(RuntimePackedEventCollectionSummary {
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()),
packed_state_version: 0x3e9,
packed_state_version_hex: "0x000003e9".to_string(),
live_id_bound: 1,
live_record_count: 1,
live_entry_ids: vec![1],
decoded_record_count: 1,
imported_runtime_record_count: 0,
records: vec![RuntimePackedEventRecordSummary {
record_index: 0,
live_entry_id: 1,
payload_offset: Some(0),
payload_len: Some(0),
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: None,
compact_control: None,
text_bands: Vec::new(),
standalone_condition_row_count: 0,
standalone_condition_rows: Vec::new(),
negative_sentinel_scope: None,
grouped_effect_row_counts: vec![1, 0, 0, 0],
grouped_effect_rows: Vec::new(),
grouped_company_targets: Vec::new(),
decoded_conditions: Vec::new(),
decoded_actions: Vec::new(),
executable_import_ready: false,
import_outcome: Some("blocked_shell_owned_descriptor".to_string()),
notes: Vec::new(),
}],
}),
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::default(),
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(summary.packed_event_blocked_shell_owned_descriptor_count, 1);
}
#[test]
fn summarizes_selected_company_market_state() {
let state = RuntimeState {
calendar: CalendarPoint {
year: 1830,
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(2),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 1,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: crate::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(1),
players: Vec::new(),
selected_player_id: None,
chairman_profiles: vec![crate::RuntimeChairmanProfile {
profile_id: 1,
name: "Chairman One".to_string(),
active: true,
current_cash: 0,
linked_company_id: Some(1),
company_holdings: std::collections::BTreeMap::from([(1, 5_000)]),
holdings_value_total: 0,
net_worth_total: 0,
purchasing_power_total: 0,
}],
selected_chairman_profile_id: Some(1),
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([(
1,
crate::RuntimeCompanyMarketState {
outstanding_shares: 20_000,
bond_count: 2,
live_bond_slots: Vec::new(),
highest_coupon_live_bond_principal: Some(350_000),
largest_live_bond_principal: Some(500_000),
mutable_support_scalar_raw_u32: 0x3f800000,
young_company_support_scalar_raw_u32: 0x42340000,
support_progress_word: 12,
recent_per_share_cache_absolute_counter: 42,
recent_per_share_cached_value_bits: 14.5f64.to_bits(),
recent_per_share_subscore_raw_u32: 0x420c0000,
cached_share_price_raw_u32: 0x42200000,
chairman_salary_baseline: 24,
chairman_salary_current: 30,
chairman_bonus_year: 1842,
chairman_bonus_amount: 750,
founding_year: 1831,
last_bankruptcy_year: 0,
last_dividend_year: 1841,
current_issue_calendar_word: 5,
current_issue_calendar_word_2: 6,
prior_issue_calendar_word: 4,
prior_issue_calendar_word_2: 5,
city_connection_latch: true,
linked_transit_latch: false,
stat_band_root_0cfb_candidates: vec![
crate::RuntimeCompanyStatBandCandidate {
label: "stat_band_0cfb_word_1".to_string(),
relative_offset: 0x0cfb,
relative_offset_hex: "0xcfb".to_string(),
raw_u32: 1,
raw_u32_hex: "0x00000001".to_string(),
value_i32: 1,
value_f32_text: "0.000000".to_string(),
},
crate::RuntimeCompanyStatBandCandidate {
label: "stat_band_0cfb_word_2".to_string(),
relative_offset: 0x0cff,
relative_offset_hex: "0xcff".to_string(),
raw_u32: 2,
raw_u32_hex: "0x00000002".to_string(),
value_i32: 2,
value_f32_text: "0.000000".to_string(),
},
],
stat_band_root_0d7f_candidates: vec![
crate::RuntimeCompanyStatBandCandidate {
label: "stat_band_0d7f_word_1".to_string(),
relative_offset: 0x0d7f,
relative_offset_hex: "0xd7f".to_string(),
raw_u32: 3,
raw_u32_hex: "0x00000003".to_string(),
value_i32: 3,
value_f32_text: "0.000000".to_string(),
},
],
stat_band_root_1c47_candidates: vec![
crate::RuntimeCompanyStatBandCandidate {
label: "stat_band_1c47_word_1".to_string(),
relative_offset: 0x1c47,
relative_offset_hex: "0x1c47".trim_start_matches("0x").to_string(),
raw_u32: 4,
raw_u32_hex: "0x00000004".to_string(),
value_i32: 4,
value_f32_text: "0.000000".to_string(),
},
],
year_stat_family_qword_bits: Vec::new(),
special_stat_family_232a_qword_bits: Vec::new(),
issue_opinion_terms_raw_i32: Vec::new(),
direct_control_transfer_float_fields_raw_u32: BTreeMap::new(),
direct_control_transfer_int_fields_raw_u32: BTreeMap::new(),
},
)]),
company_periodic_side_latch_state: BTreeMap::from([(
1,
crate::RuntimeCompanyPeriodicSideLatchState {
preferred_locomotive_engine_type_raw_u8: Some(2),
city_connection_latch: true,
linked_transit_latch: false,
},
)]),
..RuntimeServiceState::default()
},
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(summary.company_market_state_owner_count, 1);
assert_eq!(summary.selected_company_outstanding_shares, Some(20_000));
assert_eq!(summary.selected_company_bond_count, Some(2));
assert_eq!(
summary.selected_company_largest_live_bond_principal,
Some(500_000)
);
assert_eq!(
summary.selected_company_highest_coupon_live_bond_principal,
Some(350_000)
);
assert_eq!(summary.selected_company_assigned_share_pool, Some(5_000));
assert_eq!(summary.selected_company_unassigned_share_pool, Some(15_000));
assert_eq!(summary.selected_company_cached_share_price, Some(40));
assert_eq!(
summary.selected_company_cached_share_price_value_f32_text,
Some("40.000000".to_string())
);
assert_eq!(
summary.selected_company_recent_per_share_cache_absolute_counter,
Some(42)
);
assert_eq!(
summary.selected_company_recent_per_share_cached_value_f64_text,
Some("14.500000".to_string())
);
assert_eq!(
summary.selected_company_recent_per_share_subscore_value_f32_text,
Some("35.000000".to_string())
);
assert_eq!(
summary.selected_company_mutable_support_scalar_value_f32_text,
Some("1.000000".to_string())
);
assert_eq!(summary.selected_company_stat_band_root_0cfb_count, 2);
assert_eq!(summary.selected_company_stat_band_root_0d7f_count, 1);
assert_eq!(summary.selected_company_stat_band_root_1c47_count, 1);
assert_eq!(summary.selected_company_last_dividend_year, Some(1841));
assert_eq!(summary.selected_company_years_since_founding, None);
assert_eq!(summary.selected_company_years_since_last_bankruptcy, None);
assert_eq!(summary.selected_company_years_since_last_dividend, None);
assert_eq!(
summary.selected_company_periodic_side_latch_preferred_locomotive_engine_type_raw_u8,
Some(2)
);
assert_eq!(
summary.selected_company_periodic_side_latch_city_connection_latch,
Some(true)
);
assert_eq!(
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.active_periodic_route_preference_override_company_id,
None
);
assert_eq!(
summary.last_periodic_route_preference_override_company_id,
None
);
assert_eq!(summary.periodic_route_preference_override_apply_count, 0);
assert_eq!(summary.periodic_route_preference_override_restore_count, 0);
assert_eq!(summary.selected_company_chairman_bonus_year, Some(1842));
assert_eq!(summary.selected_company_chairman_bonus_amount, Some(750));
}
#[test]
fn summarizes_selected_company_creditor_pressure_branch_state() {
let mut year_stat_family_qword_bits = vec![
0u64;
((crate::RUNTIME_COMPANY_STAT_SLOT_COUNT + 2)
* crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
as usize
];
let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
let index = (slot_id * crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
bits[index] = value.to_bits();
};
let write_prior_year_value =
|bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
let index =
(slot_id * crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
bits[index] = value.to_bits();
};
write_current_value(&mut year_stat_family_qword_bits, 0x09, -50_000.0);
write_current_value(&mut year_stat_family_qword_bits, 0x0d, -700_000.0);
write_current_value(&mut year_stat_family_qword_bits, 0x12, 0.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 100_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 90_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 3, 80_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -115_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -110_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 3, -110_000.0);
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 {
packed_year_word_raw_u16: Some(1845),
partial_year_progress_raw_u8: Some(0x0c),
bankruptcy_policy_raw_u8: Some(0),
bankruptcy_allowed: Some(true),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 7,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: crate::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(7),
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([(
7,
crate::RuntimeCompanyMarketState {
founding_year: 1841,
last_bankruptcy_year: 1832,
cached_share_price_raw_u32: 25.0f32.to_bits(),
year_stat_family_qword_bits,
..crate::RuntimeCompanyMarketState::default()
},
)]),
..RuntimeServiceState::default()
},
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(
summary.selected_company_creditor_pressure_recent_bad_net_profit_year_count,
Some(3)
);
assert_eq!(
summary.selected_company_creditor_pressure_recent_peak_revenue,
Some(100_000)
);
assert_eq!(
summary.selected_company_creditor_pressure_recent_three_year_net_profit_total,
Some(-65_000)
);
assert_eq!(
summary.selected_company_creditor_pressure_cash_floor,
Some(-600_000)
);
assert_eq!(
summary.selected_company_creditor_pressure_cash_plus_slot_12_total,
Some(-700_000)
);
assert_eq!(
summary.selected_company_creditor_pressure_share_price_floor,
Some(20)
);
assert_eq!(
summary.selected_company_creditor_pressure_share_price_scalar,
Some(25)
);
assert_eq!(
summary.selected_company_creditor_pressure_current_fuel_cost,
Some(-50_000)
);
assert_eq!(
summary.selected_company_creditor_pressure_current_fuel_cost_floor,
Some(-48_000)
);
assert_eq!(
summary.selected_company_creditor_pressure_eligible_for_bankruptcy_branch,
Some(true)
);
}
#[test]
fn summarizes_selected_company_deep_distress_fallback_state() {
let mut year_stat_family_qword_bits = vec![
0u64;
((crate::RUNTIME_COMPANY_STAT_SLOT_COUNT + 2)
* crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
as usize
];
let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
let index = (slot_id * crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
bits[index] = value.to_bits();
};
let write_prior_year_value =
|bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
let index =
(slot_id * crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
bits[index] = value.to_bits();
};
write_current_value(&mut year_stat_family_qword_bits, 0x0d, -350_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 10_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 15_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 3, 12_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -35_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -38_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 3, -33_000.0);
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 {
packed_year_word_raw_u16: Some(1845),
bankruptcy_policy_raw_u8: Some(0),
bankruptcy_allowed: Some(true),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 9,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: crate::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(9),
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([(
9,
crate::RuntimeCompanyMarketState {
founding_year: 1841,
last_bankruptcy_year: 1840,
year_stat_family_qword_bits,
..crate::RuntimeCompanyMarketState::default()
},
)]),
..RuntimeServiceState::default()
},
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(
summary.selected_company_deep_distress_current_cash,
Some(-350_000)
);
assert_eq!(
summary.selected_company_deep_distress_recent_first_three_net_profit_years,
vec![-25_000, -23_000, -21_000]
);
assert_eq!(
summary.selected_company_deep_distress_cash_floor,
Some(-300_000)
);
assert_eq!(
summary.selected_company_deep_distress_net_profit_floor,
Some(-20_000)
);
assert_eq!(
summary.selected_company_deep_distress_eligible_for_bankruptcy_fallback,
Some(true)
);
}
#[test]
fn summarizes_selected_company_stock_repurchase_state() {
let mut year_stat_family_qword_bits = vec![
0u64;
((crate::RUNTIME_COMPANY_STAT_SLOT_COUNT + 2)
* crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
as usize
];
let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
let index = (slot_id * crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
bits[index] = value.to_bits();
};
write_current_value(&mut year_stat_family_qword_bits, 0x0d, 1_600_000.0);
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 {
partial_year_progress_raw_u8: Some(0x0c),
stock_issue_and_buyback_policy_raw_u8: Some(0),
stock_issue_and_buyback_allowed: Some(true),
building_density_growth_setting_raw_u32: Some(1),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 12,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: crate::RuntimeCompanyControllerKind::Unknown,
linked_chairman_profile_id: Some(3),
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(12),
players: Vec::new(),
selected_player_id: None,
chairman_profiles: vec![crate::RuntimeChairmanProfile {
profile_id: 3,
name: "Jay".to_string(),
active: true,
current_cash: 200,
linked_company_id: Some(12),
company_holdings: BTreeMap::from([(12, 14_500)]),
holdings_value_total: 0,
net_worth_total: 0,
purchasing_power_total: 0,
}],
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: Vec::new().into_iter().collect(),
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([(
12,
crate::RuntimeCompanyMarketState {
outstanding_shares: 20_000,
cached_share_price_raw_u32: 20.0f32.to_bits(),
founding_year: 1835,
city_connection_latch: true,
year_stat_family_qword_bits,
..crate::RuntimeCompanyMarketState::default()
},
)]),
chairman_personality_raw_u8: BTreeMap::from([(3, 20)]),
..RuntimeServiceState::default()
},
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(
summary.world_restore_building_density_growth_setting_raw_u32,
Some(1)
);
assert_eq!(
summary.selected_company_stock_repurchase_building_density_growth_setting,
Some(1)
);
assert_eq!(
summary.selected_company_stock_repurchase_linked_chairman_personality_raw_u8,
Some(20)
);
assert_eq!(
summary.selected_company_stock_repurchase_batch_size,
Some(1_000)
);
assert_eq!(
summary.selected_company_stock_repurchase_factor_basis_points,
Some(432)
);
assert_eq!(
summary.selected_company_stock_repurchase_current_cash,
Some(1_600_000)
);
assert_eq!(
summary.selected_company_stock_repurchase_stock_value_gate_cash_floor,
Some(3_456_000)
);
assert_eq!(
summary.selected_company_stock_repurchase_support_adjusted_share_price_scalar,
Some(20)
);
assert_eq!(
summary.selected_company_stock_repurchase_affordability_cash_floor,
Some(103_680)
);
assert_eq!(
summary.selected_company_stock_repurchase_unassigned_share_pool,
Some(5_500)
);
assert_eq!(
summary.selected_company_stock_repurchase_eligible_for_single_batch,
Some(false)
);
}
#[test]
fn summarizes_selected_company_annual_bond_policy_state() {
let mut year_stat_family_qword_bits = vec![
0u64;
((crate::RUNTIME_COMPANY_STAT_SLOT_COUNT + 2)
* crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
as usize
];
year_stat_family_qword_bits[(crate::RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH
* crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
as usize] = (-400_000.0f64).to_bits();
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 {
partial_year_progress_raw_u8: Some(0x0c),
bond_issue_and_repayment_policy_raw_u8: Some(0),
bond_issue_and_repayment_allowed: Some(true),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 11,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: crate::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(11),
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: Vec::new().into_iter().collect(),
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([(
11,
crate::RuntimeCompanyMarketState {
bond_count: 2,
linked_transit_latch: true,
live_bond_slots: vec![
crate::RuntimeCompanyBondSlot {
slot_index: 0,
principal: 200_000,
maturity_year: 0,
coupon_rate_raw_u32: 0.09f32.to_bits(),
},
crate::RuntimeCompanyBondSlot {
slot_index: 1,
principal: 150_000,
maturity_year: 0,
coupon_rate_raw_u32: 0.08f32.to_bits(),
},
],
year_stat_family_qword_bits,
..crate::RuntimeCompanyMarketState::default()
},
)]),
..RuntimeServiceState::default()
},
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(
summary.selected_company_annual_bond_linked_transit_latch,
Some(true)
);
assert_eq!(
summary.selected_company_annual_bond_live_bond_count,
Some(2)
);
assert_eq!(
summary.selected_company_annual_bond_live_bond_principal_total,
Some(350_000)
);
assert_eq!(
summary.selected_company_annual_bond_matured_live_bond_count,
Some(0)
);
assert_eq!(
summary.selected_company_annual_bond_matured_live_bond_principal_total,
Some(0)
);
assert_eq!(
summary.selected_company_annual_bond_next_live_bond_maturity_year,
None
);
assert_eq!(
summary.selected_company_annual_bond_live_bond_coupon_burden_total,
Some(30_000)
);
assert_eq!(
summary.selected_company_annual_bond_current_cash,
Some(-400_000)
);
assert_eq!(
summary.selected_company_annual_bond_cash_after_full_repayment,
Some(-750_000)
);
assert_eq!(
summary.selected_company_annual_bond_issue_cash_floor,
Some(-30_000)
);
assert_eq!(
summary.selected_company_annual_bond_issue_principal_step,
Some(500_000)
);
assert_eq!(
summary.selected_company_annual_bond_proposed_issue_bond_count,
Some(2)
);
assert_eq!(
summary.selected_company_annual_bond_proposed_issue_total_principal,
Some(1_000_000)
);
assert_eq!(
summary.selected_company_annual_bond_proposed_issue_years_to_maturity,
Some(30)
);
assert_eq!(
summary.selected_company_annual_bond_eligible_for_issue_branch,
Some(true)
);
}
#[test]
fn summarizes_selected_company_stock_issue_state() {
let mut year_stat_family_qword_bits = vec![
0u64;
((crate::RUNTIME_COMPANY_STAT_SLOT_COUNT + 2)
* crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
as usize
];
year_stat_family_qword_bits[(crate::RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH
* crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
as usize] = 250_000.0f64.to_bits();
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 {
partial_year_progress_raw_u8: Some(0x0c),
stock_issue_and_buyback_policy_raw_u8: Some(0),
stock_issue_and_buyback_allowed: Some(true),
bond_issue_and_repayment_policy_raw_u8: Some(0),
bond_issue_and_repayment_allowed: Some(true),
issue_37_value: Some(2),
issue_37_multiplier_raw_u32: Some(1.0f32.to_bits()),
issue_37_multiplier_value_f32_text: Some("1.000000".to_string()),
absolute_counter_raw_u32: Some(885_911_040),
..RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![RuntimeCompany {
company_id: 14,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: crate::RuntimeCompanyControllerKind::Unknown,
linked_chairman_profile_id: Some(8),
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(14),
players: Vec::new(),
selected_player_id: None,
chairman_profiles: vec![crate::RuntimeChairmanProfile {
profile_id: 8,
name: "Taylor".to_string(),
active: true,
current_cash: 200,
linked_company_id: Some(14),
company_holdings: BTreeMap::from([(14, 14_000)]),
holdings_value_total: 0,
net_worth_total: 0,
purchasing_power_total: 0,
}],
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: Vec::new().into_iter().collect(),
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 {
world_issue_opinion_base_terms_raw_i32: vec![0; 0x3b],
chairman_personality_raw_u8: BTreeMap::from([(8, 20)]),
annual_finance_last_actions: BTreeMap::from([(
14,
crate::RuntimeCompanyAnnualFinancePolicyAction::StockIssue,
)]),
annual_finance_last_news_family_candidates: BTreeMap::from([(
14,
"4053".to_string(),
)]),
annual_finance_last_news_events: vec![crate::RuntimeAnnualFinanceNewsEvent {
company_id: 14,
selector_label: "4053".to_string(),
action_label: "stock_issue".to_string(),
retired_principal_total: 0,
issued_principal_total: 0,
repurchased_share_count: 0,
issued_share_count: 4_000,
}],
company_market_state: BTreeMap::from([(
14,
crate::RuntimeCompanyMarketState {
outstanding_shares: 20_000,
bond_count: 2,
highest_coupon_live_bond_principal: Some(300_000),
current_issue_calendar_word: 0x0101_0725,
current_issue_calendar_word_2: 0x0001_0001,
founding_year: 1840,
cached_share_price_raw_u32: 35.0f32.to_bits(),
recent_per_share_cache_absolute_counter: 885_911_040,
recent_per_share_cached_value_bits: 34.0f64.to_bits(),
live_bond_slots: vec![
crate::RuntimeCompanyBondSlot {
slot_index: 0,
principal: 300_000,
maturity_year: 0,
coupon_rate_raw_u32: 0.11f32.to_bits(),
},
crate::RuntimeCompanyBondSlot {
slot_index: 1,
principal: 200_000,
maturity_year: 0,
coupon_rate_raw_u32: 0.07f32.to_bits(),
},
],
direct_control_transfer_float_fields_raw_u32: BTreeMap::from([(
0x32f,
30.0f32.to_bits(),
)]),
year_stat_family_qword_bits,
..crate::RuntimeCompanyMarketState::default()
},
)]),
..RuntimeServiceState::default()
},
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(
summary.selected_company_stock_issue_live_bond_count,
Some(2)
);
assert_eq!(
summary.selected_company_stock_issue_initial_batch_size,
Some(2_000)
);
assert_eq!(
summary.selected_company_stock_issue_trimmed_batch_size,
Some(2_000)
);
assert_eq!(
summary.selected_company_stock_issue_share_pressure_basis_points,
Some(-1_000)
);
assert_eq!(
summary.selected_company_stock_issue_pressured_share_price_scalar,
Some(35)
);
assert_eq!(
summary.selected_company_stock_issue_pressured_proceeds,
Some(70_000)
);
assert_eq!(
summary.selected_company_stock_issue_book_value_per_share_floor_applied,
Some(30)
);
assert_eq!(
summary.selected_company_stock_issue_price_to_book_ratio_basis_points,
Some(11_667)
);
assert_eq!(
summary.selected_company_stock_issue_current_cash,
Some(250_000)
);
assert_eq!(
summary.selected_company_stock_issue_highest_coupon_live_bond_principal,
Some(300_000)
);
assert_eq!(
summary.selected_company_stock_issue_highest_coupon_live_bond_rate_basis_points,
Some(1_100)
);
assert_eq!(
summary.selected_company_stock_issue_current_issue_age_absolute_counter_delta,
Some(967_680)
);
assert_eq!(
summary.selected_company_stock_issue_current_issue_cooldown_floor,
Some(483_840)
);
assert_eq!(
summary.selected_company_stock_issue_minimum_price_to_book_ratio_basis_points,
Some(8_000)
);
assert_eq!(
summary.selected_company_stock_issue_passes_share_price_floor,
Some(true)
);
assert_eq!(
summary.selected_company_stock_issue_passes_proceeds_floor,
Some(true)
);
assert_eq!(
summary.selected_company_stock_issue_passes_cash_gate,
Some(true)
);
assert_eq!(
summary.selected_company_stock_issue_passes_issue_cooldown_gate,
Some(true)
);
assert_eq!(
summary.selected_company_stock_issue_passes_coupon_price_to_book_gate,
Some(true)
);
assert_eq!(
summary.selected_company_stock_issue_eligible_for_double_tranche,
Some(true)
);
assert_eq!(
summary
.selected_company_annual_finance_news_family_candidate
.as_deref(),
Some("4053")
);
assert_eq!(
summary
.selected_company_annual_finance_last_news_selector
.as_deref(),
Some("4053")
);
assert_eq!(summary.annual_finance_last_news_event_count, 1);
}
#[test]
fn summarizes_selected_company_annual_dividend_policy_state() {
let mut year_stat_family_qword_bits = vec![
0u64;
((crate::RUNTIME_COMPANY_STAT_SLOT_COUNT + 2)
* crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
as usize
];
let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
let index = (slot_id * crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
bits[index] = value.to_bits();
};
let write_prior_year_value =
|bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
let index =
(slot_id * crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
bits[index] = value.to_bits();
};
write_current_value(&mut year_stat_family_qword_bits, 0x0d, 300_000.0);
write_current_value(&mut year_stat_family_qword_bits, 0x01, 300_000.0);
write_current_value(&mut year_stat_family_qword_bits, 0x09, -180_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 280_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -190_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 260_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -200_000.0);
write_prior_year_value(&mut year_stat_family_qword_bits, 0x1c, 1, 5.0);
let state = RuntimeState {
calendar: CalendarPoint {
year: 1845,
month_slot: 0,
phase_slot: 0,
tick_slot: 0,
},
world_flags: BTreeMap::new(),
save_profile: crate::RuntimeSaveProfileState::default(),
world_restore: crate::RuntimeWorldRestoreState {
packed_year_word_raw_u16: Some(1845),
partial_year_progress_raw_u8: Some(0x0c),
dividend_policy_raw_u8: Some(0),
dividend_adjustment_allowed: Some(true),
stock_issue_and_buyback_policy_raw_u8: Some(0),
stock_issue_and_buyback_allowed: Some(true),
bond_issue_and_repayment_policy_raw_u8: Some(0),
bond_issue_and_repayment_allowed: Some(true),
bankruptcy_policy_raw_u8: Some(0),
bankruptcy_allowed: Some(true),
building_density_growth_setting_raw_u32: Some(1),
..crate::RuntimeWorldRestoreState::default()
},
metadata: BTreeMap::new(),
companies: vec![crate::RuntimeCompany {
company_id: 15,
current_cash: 0,
debt: 0,
credit_rating_score: None,
prime_rate: None,
active: true,
available_track_laying_capacity: None,
controller_kind: crate::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: crate::RuntimeTrackPieceCounts::default(),
}],
selected_company_id: Some(15),
players: Vec::new(),
selected_player_id: None,
chairman_profiles: vec![crate::RuntimeChairmanProfile {
profile_id: 3,
name: "Chairman Three".to_string(),
active: true,
current_cash: 0,
linked_company_id: Some(15),
company_holdings: BTreeMap::from([(15, 9_500)]),
holdings_value_total: 0,
net_worth_total: 0,
purchasing_power_total: 0,
}],
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: crate::RuntimeServiceState {
company_market_state: BTreeMap::from([(
15,
crate::RuntimeCompanyMarketState {
outstanding_shares: 10_000,
founding_year: 1840,
last_dividend_year: 1844,
year_stat_family_qword_bits,
direct_control_transfer_float_fields_raw_u32: BTreeMap::from([(
0x33f,
0.4f32.to_bits(),
)]),
..crate::RuntimeCompanyMarketState::default()
},
)]),
..crate::RuntimeServiceState::default()
},
};
let summary = RuntimeSummary::from_state(&state);
assert_eq!(
summary.selected_company_dividend_weighted_recent_net_profit_total,
Some(600_000)
);
assert_eq!(
summary.selected_company_dividend_weighted_recent_net_profit_average,
Some(100_000)
);
assert_eq!(
summary.selected_company_dividend_current_cash,
Some(300_000)
);
assert_eq!(
summary.selected_company_dividend_tiny_unassigned_share_cash_supplement_branch,
Some(true)
);
assert_eq!(
summary.selected_company_dividend_tentative_target_per_share_tenths,
Some(133)
);
assert_eq!(
summary.selected_company_dividend_current_per_share_tenths,
Some(4)
);
assert_eq!(
summary.selected_company_dividend_growth_adjusted_current_per_share_tenths,
Some(3)
);
assert_eq!(
summary.selected_company_dividend_board_approved_ceiling_tenths,
Some(18)
);
assert_eq!(
summary.selected_company_dividend_proposed_per_share_tenths,
Some(18)
);
assert_eq!(
summary.selected_company_dividend_eligible_for_adjustment_branch,
Some(true)
);
assert_eq!(
summary
.selected_company_annual_finance_policy_action
.as_deref(),
Some("dividend_adjustment")
);
assert_eq!(
summary.selected_company_annual_finance_policy_dividend_adjustment_eligible,
Some(true)
);
}
}