Sync company finance leaves from owner state
This commit is contained in:
parent
fd6046a85c
commit
f06ca01826
2 changed files with 257 additions and 3 deletions
|
|
@ -2267,6 +2267,37 @@ impl RuntimeState {
|
|||
})
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
|
||||
let company_refresh = self
|
||||
.companies
|
||||
.iter()
|
||||
.map(|company| {
|
||||
let current_cash = runtime_company_control_transfer_stat_value_f64(
|
||||
self,
|
||||
company.company_id,
|
||||
RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
|
||||
)
|
||||
.and_then(runtime_round_f64_to_i64);
|
||||
let book_value_per_share =
|
||||
runtime_company_direct_float_field_value_f64(self, company.company_id, 0x32f)
|
||||
.and_then(runtime_round_f64_to_i64);
|
||||
(company.company_id, current_cash, book_value_per_share)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for company in &mut self.companies {
|
||||
if let Some((_, current_cash, book_value_per_share)) = company_refresh
|
||||
.iter()
|
||||
.find(|(company_id, _, _)| *company_id == company.company_id)
|
||||
{
|
||||
if let Some(current_cash) = current_cash {
|
||||
company.current_cash = *current_cash;
|
||||
}
|
||||
if let Some(book_value_per_share) = book_value_per_share {
|
||||
company.book_value_per_share = *book_value_per_share;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for profile in &mut self.chairman_profiles {
|
||||
let preserved_threshold_adjusted_holdings_component = profile
|
||||
.purchasing_power_total
|
||||
|
|
@ -6192,6 +6223,96 @@ mod tests {
|
|||
assert_eq!(state.chairman_profiles[0].purchasing_power_total, 130);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn refreshes_company_leaf_fields_from_owner_state() {
|
||||
let mut year_stat_family_qword_bits = vec![
|
||||
0u64;
|
||||
((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
|
||||
as usize
|
||||
];
|
||||
year_stat_family_qword_bits[(RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH
|
||||
* RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
|
||||
as usize] = 275.0f64.to_bits();
|
||||
|
||||
let mut 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,
|
||||
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,
|
||||
}],
|
||||
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([(
|
||||
1,
|
||||
RuntimeCompanyMarketState {
|
||||
direct_control_transfer_float_fields_raw_u32: BTreeMap::from([(
|
||||
0x32f,
|
||||
2620.0f32.to_bits(),
|
||||
)]),
|
||||
year_stat_family_qword_bits,
|
||||
..RuntimeCompanyMarketState::default()
|
||||
},
|
||||
)]),
|
||||
..RuntimeServiceState::default()
|
||||
},
|
||||
};
|
||||
|
||||
state.refresh_derived_market_state();
|
||||
|
||||
assert_eq!(state.companies[0].current_cash, 275);
|
||||
assert_eq!(state.companies[0].book_value_per_share, 2620);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_grounded_company_stat_family_slots_from_runtime_state() {
|
||||
let mut year_stat_family_qword_bits = vec![
|
||||
|
|
|
|||
|
|
@ -1188,14 +1188,32 @@ fn apply_runtime_effects(
|
|||
RuntimeEffect::SetCompanyCash { target, value } => {
|
||||
let company_ids = resolve_company_target_ids(state, target, condition_context)?;
|
||||
for company_id in company_ids {
|
||||
let company = state
|
||||
let prior_cash = state
|
||||
.companies
|
||||
.iter_mut()
|
||||
.iter()
|
||||
.find(|company| company.company_id == company_id)
|
||||
.map(|company| company.current_cash)
|
||||
.ok_or_else(|| {
|
||||
format!("missing company_id {company_id} while applying cash effect")
|
||||
})?;
|
||||
company.current_cash = *value;
|
||||
if !service_post_company_stat_delta(
|
||||
state,
|
||||
company_id,
|
||||
RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
|
||||
value.saturating_sub(prior_cash),
|
||||
false,
|
||||
) {
|
||||
let company = state
|
||||
.companies
|
||||
.iter_mut()
|
||||
.find(|company| company.company_id == company_id)
|
||||
.ok_or_else(|| {
|
||||
format!(
|
||||
"missing company_id {company_id} while applying cash effect"
|
||||
)
|
||||
})?;
|
||||
company.current_cash = *value;
|
||||
}
|
||||
mutated_company_ids.insert(company_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -4223,6 +4241,121 @@ mod tests {
|
|||
assert_eq!(result.service_events[0].mutated_company_ids, vec![2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_company_cash_updates_owner_state_backed_current_cash() {
|
||||
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] = 100.0f64.to_bits();
|
||||
|
||||
let mut state = RuntimeState {
|
||||
companies: vec![RuntimeCompany {
|
||||
company_id: 1,
|
||||
controller_kind: RuntimeCompanyControllerKind::Unknown,
|
||||
current_cash: 100,
|
||||
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,
|
||||
}],
|
||||
event_runtime_records: vec![RuntimeEventRecord {
|
||||
record_id: 10,
|
||||
trigger_kind: 7,
|
||||
active: true,
|
||||
service_count: 0,
|
||||
marks_collection_dirty: false,
|
||||
one_shot: false,
|
||||
has_fired: false,
|
||||
conditions: Vec::new(),
|
||||
effects: vec![RuntimeEffect::SetCompanyCash {
|
||||
target: RuntimeCompanyTarget::Ids { ids: vec![1] },
|
||||
value: 250,
|
||||
}],
|
||||
}],
|
||||
service_state: RuntimeServiceState {
|
||||
company_market_state: BTreeMap::from([(
|
||||
1,
|
||||
crate::RuntimeCompanyMarketState {
|
||||
year_stat_family_qword_bits,
|
||||
special_stat_family_232a_qword_bits: vec![0u64; 0x20],
|
||||
..crate::RuntimeCompanyMarketState::default()
|
||||
},
|
||||
)]),
|
||||
..RuntimeServiceState::default()
|
||||
},
|
||||
calendar: crate::CalendarPoint {
|
||||
year: 1830,
|
||||
month_slot: 0,
|
||||
phase_slot: 0,
|
||||
tick_slot: 0,
|
||||
},
|
||||
world_flags: BTreeMap::new(),
|
||||
save_profile: crate::RuntimeSaveProfileState::default(),
|
||||
world_restore: crate::RuntimeWorldRestoreState::default(),
|
||||
metadata: BTreeMap::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,
|
||||
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(),
|
||||
};
|
||||
|
||||
execute_step_command(
|
||||
&mut state,
|
||||
&StepCommand::ServiceTriggerKind { trigger_kind: 7 },
|
||||
)
|
||||
.expect("cash effect should apply through owner state");
|
||||
|
||||
assert_eq!(state.companies[0].current_cash, 250);
|
||||
assert_eq!(
|
||||
crate::runtime::runtime_company_stat_value(
|
||||
&state,
|
||||
1,
|
||||
crate::RuntimeCompanyStatSelector {
|
||||
family_id: crate::RUNTIME_COMPANY_STAT_FAMILY_CONTROL_TRANSFER,
|
||||
slot_id: crate::RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
|
||||
},
|
||||
),
|
||||
Some(250)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn applies_named_locomotive_availability_effects() {
|
||||
let mut state = RuntimeState {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue