Carry trailing finance lanes into annual state
This commit is contained in:
parent
cbf0dbeda5
commit
dbca9a2e78
1 changed files with 164 additions and 0 deletions
|
|
@ -135,6 +135,14 @@ pub struct RuntimeCompanyAnnualFinanceState {
|
|||
#[serde(default)]
|
||||
pub current_partial_year_weight_numerator: Option<i64>,
|
||||
#[serde(default)]
|
||||
pub trailing_full_year_year_words: Vec<u32>,
|
||||
#[serde(default)]
|
||||
pub trailing_full_year_net_profits: Vec<i64>,
|
||||
#[serde(default)]
|
||||
pub trailing_full_year_revenues: Vec<i64>,
|
||||
#[serde(default)]
|
||||
pub trailing_full_year_fuel_costs: Vec<i64>,
|
||||
#[serde(default)]
|
||||
pub current_issue_absolute_counter: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub prior_issue_absolute_counter: Option<u32>,
|
||||
|
|
@ -2054,6 +2062,29 @@ fn runtime_divide_by_rounded_stat_i64(numerator: f64, denominator: i64) -> Optio
|
|||
Some(numerator / denominator as f64)
|
||||
}
|
||||
|
||||
fn runtime_company_trailing_full_year_stat_series(
|
||||
state: &RuntimeState,
|
||||
company_id: u32,
|
||||
slot_id: u32,
|
||||
full_year_count: u32,
|
||||
) -> Option<(Vec<u32>, Vec<i64>)> {
|
||||
let current_year_word = u32::from(state.world_restore.packed_year_word_raw_u16?);
|
||||
let mut year_words = Vec::with_capacity(full_year_count as usize);
|
||||
let mut values = Vec::with_capacity(full_year_count as usize);
|
||||
for year_offset in 1..=full_year_count {
|
||||
let family_id = current_year_word.checked_sub(year_offset)?;
|
||||
let value = runtime_company_stat_value_f64(
|
||||
state,
|
||||
company_id,
|
||||
RuntimeCompanyStatSelector { family_id, slot_id },
|
||||
)
|
||||
.and_then(runtime_round_f64_to_i64)?;
|
||||
year_words.push(family_id);
|
||||
values.push(value);
|
||||
}
|
||||
Some((year_words, values))
|
||||
}
|
||||
|
||||
pub fn runtime_world_issue_state(
|
||||
state: &RuntimeState,
|
||||
issue_id: u32,
|
||||
|
|
@ -2196,6 +2227,15 @@ pub fn runtime_company_annual_finance_state(
|
|||
}
|
||||
_ => None,
|
||||
};
|
||||
let (trailing_full_year_year_words, trailing_full_year_net_profits) =
|
||||
runtime_company_trailing_full_year_stat_series(state, company_id, 0x2b, 4)
|
||||
.unwrap_or_default();
|
||||
let (_, trailing_full_year_revenues) =
|
||||
runtime_company_trailing_full_year_stat_series(state, company_id, 0x2c, 4)
|
||||
.unwrap_or_default();
|
||||
let (_, trailing_full_year_fuel_costs) =
|
||||
runtime_company_trailing_full_year_stat_series(state, company_id, 0x09, 4)
|
||||
.unwrap_or_default();
|
||||
Some(RuntimeCompanyAnnualFinanceState {
|
||||
company_id,
|
||||
outstanding_shares: market_state.outstanding_shares,
|
||||
|
|
@ -2216,6 +2256,10 @@ pub fn runtime_company_annual_finance_state(
|
|||
years_since_last_bankruptcy,
|
||||
years_since_last_dividend,
|
||||
current_partial_year_weight_numerator: runtime_world_partial_year_weight_numerator(state),
|
||||
trailing_full_year_year_words,
|
||||
trailing_full_year_net_profits,
|
||||
trailing_full_year_revenues,
|
||||
trailing_full_year_fuel_costs,
|
||||
current_issue_absolute_counter,
|
||||
prior_issue_absolute_counter,
|
||||
current_issue_age_absolute_counter_delta,
|
||||
|
|
@ -4485,6 +4529,122 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn carries_trailing_full_year_finance_lanes_into_annual_finance_state() {
|
||||
let mut year_stat_family_qword_bits =
|
||||
vec![0u64; (RUNTIME_COMPANY_STAT_SLOT_COUNT * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize];
|
||||
let write_year_value = |bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
|
||||
let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
|
||||
bits[index] = value.to_bits();
|
||||
};
|
||||
for (year_delta, revenue_parts, extra_profit_parts, fuel_cost) in [
|
||||
(1, [60.0, 50.0, 40.0, 30.0], [10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0], 18.0),
|
||||
(2, [50.0, 45.0, 40.0, 35.0], [9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0], 17.0),
|
||||
(3, [50.0, 40.0, 35.0, 35.0], [8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0], 16.0),
|
||||
(4, [45.0, 40.0, 35.0, 30.0], [7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0], 15.0),
|
||||
] {
|
||||
for (slot_id, value) in [0x01, 0x02, 0x03, 0x04]
|
||||
.into_iter()
|
||||
.zip(revenue_parts)
|
||||
{
|
||||
write_year_value(&mut year_stat_family_qword_bits, slot_id, year_delta, value);
|
||||
}
|
||||
for (slot_id, value) in [0x05, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c]
|
||||
.into_iter()
|
||||
.zip(extra_profit_parts)
|
||||
{
|
||||
write_year_value(&mut year_stat_family_qword_bits, slot_id, year_delta, value);
|
||||
}
|
||||
write_year_value(&mut year_stat_family_qword_bits, 0x09, year_delta, fuel_cost);
|
||||
}
|
||||
|
||||
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),
|
||||
..RuntimeWorldRestoreState::default()
|
||||
},
|
||||
metadata: BTreeMap::new(),
|
||||
companies: vec![RuntimeCompany {
|
||||
company_id: 7,
|
||||
current_cash: 125_000,
|
||||
debt: 0,
|
||||
credit_rating_score: None,
|
||||
prime_rate: None,
|
||||
active: true,
|
||||
available_track_laying_capacity: None,
|
||||
controller_kind: RuntimeCompanyControllerKind::Unknown,
|
||||
linked_chairman_profile_id: None,
|
||||
book_value_per_share: 2_620,
|
||||
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::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,
|
||||
RuntimeCompanyMarketState {
|
||||
outstanding_shares: 20_000,
|
||||
year_stat_family_qword_bits,
|
||||
..RuntimeCompanyMarketState::default()
|
||||
},
|
||||
)]),
|
||||
..RuntimeServiceState::default()
|
||||
},
|
||||
};
|
||||
|
||||
let finance_state =
|
||||
runtime_company_annual_finance_state(&state, 7).expect("annual finance state");
|
||||
assert_eq!(
|
||||
finance_state.trailing_full_year_year_words,
|
||||
vec![1844, 1843, 1842, 1841]
|
||||
);
|
||||
assert_eq!(
|
||||
finance_state.trailing_full_year_net_profits,
|
||||
vec![247, 229, 211, 193]
|
||||
);
|
||||
assert_eq!(finance_state.trailing_full_year_revenues, vec![180, 170, 160, 150]);
|
||||
assert_eq!(finance_state.trailing_full_year_fuel_costs, vec![18, 17, 16, 15]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_grounded_world_issue_state_from_runtime_restore_state() {
|
||||
let state = RuntimeState {
|
||||
|
|
@ -4894,6 +5054,10 @@ mod tests {
|
|||
years_since_last_bankruptcy: None,
|
||||
years_since_last_dividend: None,
|
||||
current_partial_year_weight_numerator: None,
|
||||
trailing_full_year_year_words: Vec::new(),
|
||||
trailing_full_year_net_profits: Vec::new(),
|
||||
trailing_full_year_revenues: Vec::new(),
|
||||
trailing_full_year_fuel_costs: Vec::new(),
|
||||
current_issue_absolute_counter: None,
|
||||
prior_issue_absolute_counter: None,
|
||||
current_issue_age_absolute_counter_delta: None,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue