Carry annual finance news family candidates

This commit is contained in:
Jan Petykiewicz 2026-04-18 05:38:37 -07:00
commit fb78879fac
5 changed files with 174 additions and 1 deletions

View file

@ -13997,6 +13997,7 @@ mod tests {
annual_bond_last_issued_principal_total: 0, annual_bond_last_issued_principal_total: 0,
annual_stock_repurchase_last_share_count: 0, annual_stock_repurchase_last_share_count: 0,
annual_stock_issue_last_share_count: 0, annual_stock_issue_last_share_count: 0,
annual_finance_last_news_family_candidates: BTreeMap::new(),
chairman_issue_opinion_terms_raw_i32: BTreeMap::new(), chairman_issue_opinion_terms_raw_i32: BTreeMap::new(),
chairman_personality_raw_u8: BTreeMap::new(), chairman_personality_raw_u8: BTreeMap::new(),
}, },

View file

@ -70,7 +70,8 @@ pub use runtime::{
RuntimeTerritory, RuntimeTerritoryMetric, RuntimeTerritoryTarget, RuntimeTrackMetric, RuntimeTerritory, RuntimeTerritoryMetric, RuntimeTerritoryTarget, RuntimeTrackMetric,
RuntimeTrackPieceCounts, RuntimeTrain, RuntimeWorldFinanceNeighborhoodCandidate, RuntimeTrackPieceCounts, RuntimeTrain, RuntimeWorldFinanceNeighborhoodCandidate,
RuntimeWorldIssueState, RuntimeWorldRestoreState, RuntimeWorldIssueState, RuntimeWorldRestoreState,
runtime_annual_bond_principal_flow_relation_label, runtime_company_annual_bond_policy_state, runtime_annual_bond_principal_flow_relation_label,
runtime_annual_finance_news_family_candidate_label, runtime_company_annual_bond_policy_state,
runtime_company_annual_creditor_pressure_state, runtime_company_annual_deep_distress_state, runtime_company_annual_creditor_pressure_state, runtime_company_annual_deep_distress_state,
runtime_company_annual_dividend_policy_state, runtime_company_annual_dividend_policy_state,
runtime_company_annual_finance_policy_action_label, runtime_company_annual_finance_policy_action_label,

View file

@ -1245,6 +1245,8 @@ pub struct RuntimeServiceState {
#[serde(default)] #[serde(default)]
pub annual_stock_issue_last_share_count: u64, pub annual_stock_issue_last_share_count: u64,
#[serde(default)] #[serde(default)]
pub annual_finance_last_news_family_candidates: BTreeMap<u32, String>,
#[serde(default)]
pub chairman_issue_opinion_terms_raw_i32: BTreeMap<u32, Vec<i32>>, pub chairman_issue_opinion_terms_raw_i32: BTreeMap<u32, Vec<i32>>,
#[serde(default)] #[serde(default)]
pub chairman_personality_raw_u8: BTreeMap<u32, u8>, pub chairman_personality_raw_u8: BTreeMap<u32, u8>,
@ -2155,6 +2157,18 @@ impl RuntimeState {
)); ));
} }
} }
for company_id in self
.service_state
.annual_finance_last_news_family_candidates
.keys()
{
if !seen_company_ids.contains(company_id) {
return Err(format!(
"service_state.annual_finance_last_news_family_candidates references unknown company_id {}",
company_id
));
}
}
for chairman_profile_id in self for chairman_profile_id in self
.service_state .service_state
.chairman_issue_opinion_terms_raw_i32 .chairman_issue_opinion_terms_raw_i32
@ -3649,6 +3663,33 @@ pub fn runtime_annual_bond_principal_flow_relation_label(
} }
} }
pub fn runtime_annual_finance_news_family_candidate_label(
action: RuntimeCompanyAnnualFinancePolicyAction,
retired_principal_total: u64,
issued_principal_total: u64,
repurchased_share_count: u64,
issued_share_count: u64,
) -> Option<&'static str> {
match action {
RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy
| RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback => Some("2881"),
RuntimeCompanyAnnualFinancePolicyAction::BondIssue => {
runtime_annual_bond_principal_flow_relation_label(
retired_principal_total,
issued_principal_total,
)
.map(|_| "2882_2886")
}
RuntimeCompanyAnnualFinancePolicyAction::StockRepurchase => {
(repurchased_share_count > 0).then_some("2887")
}
RuntimeCompanyAnnualFinancePolicyAction::StockIssue => {
(issued_share_count > 0).then_some("4053")
}
_ => None,
}
}
fn runtime_company_stock_issue_price_to_book_ratio_f64( fn runtime_company_stock_issue_price_to_book_ratio_f64(
pressured_support_adjusted_share_price_scalar: f64, pressured_support_adjusted_share_price_scalar: f64,
book_value_per_share: f64, book_value_per_share: f64,

View file

@ -15,6 +15,7 @@ use crate::{
RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecordTemplate, RuntimePlayerTarget, RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecordTemplate, RuntimePlayerTarget,
RuntimeState, RuntimeSummary, RuntimeTerritoryMetric, RuntimeTerritoryTarget, RuntimeState, RuntimeSummary, RuntimeTerritoryMetric, RuntimeTerritoryTarget,
RuntimeTrackMetric, RuntimeTrackPieceCounts, calendar::BoundaryEventKind, RuntimeTrackMetric, RuntimeTrackPieceCounts, calendar::BoundaryEventKind,
runtime_annual_finance_news_family_candidate_label,
runtime_company_annual_dividend_policy_state, runtime_company_annual_finance_policy_state, runtime_company_annual_dividend_policy_state, runtime_company_annual_finance_policy_state,
runtime_company_annual_stock_issue_state, runtime_company_annual_stock_repurchase_state, runtime_company_annual_stock_issue_state, runtime_company_annual_stock_repurchase_state,
runtime_company_book_value_per_share, runtime_company_credit_rating, runtime_company_book_value_per_share, runtime_company_credit_rating,
@ -499,6 +500,10 @@ fn service_company_annual_finance_policy(
.service_state .service_state
.annual_finance_last_actions .annual_finance_last_actions
.retain(|company_id, _| active_company_id_set.contains(company_id)); .retain(|company_id, _| active_company_id_set.contains(company_id));
state
.service_state
.annual_finance_last_news_family_candidates
.retain(|company_id, _| active_company_id_set.contains(company_id));
state.service_state.annual_finance_service_calls += 1; state.service_state.annual_finance_service_calls += 1;
state.service_state.annual_bond_last_retired_principal_total = 0; state.service_state.annual_bond_last_retired_principal_total = 0;
state.service_state.annual_bond_last_issued_principal_total = 0; state.service_state.annual_bond_last_issued_principal_total = 0;
@ -517,6 +522,10 @@ fn service_company_annual_finance_policy(
.service_state .service_state
.annual_finance_last_actions .annual_finance_last_actions
.insert(company_id, policy_state.action); .insert(company_id, policy_state.action);
state
.service_state
.annual_finance_last_news_family_candidates
.remove(&company_id);
*state *state
.service_state .service_state
.annual_finance_action_counts .annual_finance_action_counts
@ -554,6 +563,18 @@ fn service_company_annual_finance_policy(
crate::RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy crate::RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy
| crate::RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback => { | crate::RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback => {
if service_apply_company_bankruptcy(state, company_id) { if service_apply_company_bankruptcy(state, company_id) {
if let Some(label) = runtime_annual_finance_news_family_candidate_label(
policy_state.action,
state.service_state.annual_bond_last_retired_principal_total,
state.service_state.annual_bond_last_issued_principal_total,
state.service_state.annual_stock_repurchase_last_share_count,
state.service_state.annual_stock_issue_last_share_count,
) {
state
.service_state
.annual_finance_last_news_family_candidates
.insert(company_id, label.to_string());
}
applied_effect_count += 1; applied_effect_count += 1;
mutated_company_ids.insert(company_id); mutated_company_ids.insert(company_id);
} }
@ -626,6 +647,18 @@ fn service_company_annual_finance_policy(
market_state.current_issue_calendar_word = current_tuple_word_0; market_state.current_issue_calendar_word = current_tuple_word_0;
market_state.current_issue_calendar_word_2 = current_tuple_word_1; market_state.current_issue_calendar_word_2 = current_tuple_word_1;
if mutated { if mutated {
if let Some(label) = runtime_annual_finance_news_family_candidate_label(
policy_state.action,
state.service_state.annual_bond_last_retired_principal_total,
state.service_state.annual_bond_last_issued_principal_total,
state.service_state.annual_stock_repurchase_last_share_count,
state.service_state.annual_stock_issue_last_share_count,
) {
state
.service_state
.annual_finance_last_news_family_candidates
.insert(company_id, label.to_string());
}
applied_effect_count += 1; applied_effect_count += 1;
mutated_company_ids.insert(company_id); mutated_company_ids.insert(company_id);
} }
@ -773,6 +806,18 @@ fn service_company_annual_finance_policy(
.unwrap_or(company.debt); .unwrap_or(company.debt);
} }
if mutated { if mutated {
if let Some(label) = runtime_annual_finance_news_family_candidate_label(
policy_state.action,
state.service_state.annual_bond_last_retired_principal_total,
state.service_state.annual_bond_last_issued_principal_total,
state.service_state.annual_stock_repurchase_last_share_count,
state.service_state.annual_stock_issue_last_share_count,
) {
state
.service_state
.annual_finance_last_news_family_candidates
.insert(company_id, label.to_string());
}
applied_effect_count += 1; applied_effect_count += 1;
mutated_company_ids.insert(company_id); mutated_company_ids.insert(company_id);
} }
@ -850,6 +895,18 @@ fn service_company_annual_finance_policy(
.saturating_add(u64::from(batch_size)); .saturating_add(u64::from(batch_size));
} }
if mutated { if mutated {
if let Some(label) = runtime_annual_finance_news_family_candidate_label(
policy_state.action,
state.service_state.annual_bond_last_retired_principal_total,
state.service_state.annual_bond_last_issued_principal_total,
state.service_state.annual_stock_repurchase_last_share_count,
state.service_state.annual_stock_issue_last_share_count,
) {
state
.service_state
.annual_finance_last_news_family_candidates
.insert(company_id, label.to_string());
}
applied_effect_count += 1; applied_effect_count += 1;
mutated_company_ids.insert(company_id); mutated_company_ids.insert(company_id);
} }
@ -2909,6 +2966,13 @@ mod tests {
state.service_state.annual_finance_last_actions.get(&22), state.service_state.annual_finance_last_actions.get(&22),
Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::StockIssue) Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::StockIssue)
); );
assert_eq!(
state
.service_state
.annual_finance_last_news_family_candidates
.get(&22),
Some(&"4053".to_string())
);
assert_eq!( assert_eq!(
state.service_state.annual_stock_issue_last_share_count, state.service_state.annual_stock_issue_last_share_count,
4_000 4_000
@ -3077,6 +3141,13 @@ mod tests {
state.service_state.annual_finance_last_actions.get(&23), state.service_state.annual_finance_last_actions.get(&23),
Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::StockRepurchase) Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::StockRepurchase)
); );
assert_eq!(
state
.service_state
.annual_finance_last_news_family_candidates
.get(&23),
Some(&"2887".to_string())
);
assert_eq!(state.service_state.annual_stock_issue_last_share_count, 0); assert_eq!(state.service_state.annual_stock_issue_last_share_count, 0);
assert_eq!( assert_eq!(
state.service_state.annual_stock_repurchase_last_share_count, state.service_state.annual_stock_repurchase_last_share_count,
@ -3199,6 +3270,13 @@ mod tests {
state.service_state.annual_finance_last_actions.get(&24), state.service_state.annual_finance_last_actions.get(&24),
Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::BondIssue) Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::BondIssue)
); );
assert_eq!(
state
.service_state
.annual_finance_last_news_family_candidates
.get(&24),
Some(&"2882_2886".to_string())
);
assert_eq!(state.companies[0].current_cash, 100_000); assert_eq!(state.companies[0].current_cash, 100_000);
assert_eq!(state.service_state.company_market_state[&24].bond_count, 1); assert_eq!(state.service_state.company_market_state[&24].bond_count, 1);
assert_eq!( assert_eq!(
@ -3356,6 +3434,13 @@ mod tests {
state.service_state.annual_finance_last_actions.get(&25), state.service_state.annual_finance_last_actions.get(&25),
Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::BondIssue) Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::BondIssue)
); );
assert_eq!(
state
.service_state
.annual_finance_last_news_family_candidates
.get(&25),
Some(&"2882_2886".to_string())
);
assert_eq!(state.companies[0].current_cash, 550_000); assert_eq!(state.companies[0].current_cash, 550_000);
assert_eq!(state.companies[0].debt, 0); assert_eq!(state.companies[0].debt, 0);
assert_eq!( assert_eq!(
@ -3511,6 +3596,13 @@ mod tests {
state.service_state.annual_finance_last_actions.get(&26), state.service_state.annual_finance_last_actions.get(&26),
Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::BondIssue) Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::BondIssue)
); );
assert_eq!(
state
.service_state
.annual_finance_last_news_family_candidates
.get(&26),
Some(&"2882_2886".to_string())
);
assert_eq!(state.companies[0].current_cash, 250_000); assert_eq!(state.companies[0].current_cash, 250_000);
assert_eq!(state.companies[0].debt, 1_000_000); assert_eq!(state.companies[0].debt, 1_000_000);
assert_eq!( assert_eq!(
@ -3691,6 +3783,13 @@ mod tests {
state.service_state.annual_finance_last_actions.get(&31), state.service_state.annual_finance_last_actions.get(&31),
Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy) Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::CreditorPressureBankruptcy)
); );
assert_eq!(
state
.service_state
.annual_finance_last_news_family_candidates
.get(&31),
Some(&"2881".to_string())
);
assert_eq!(state.companies[0].current_cash, 0); assert_eq!(state.companies[0].current_cash, 0);
assert_eq!(state.companies[0].debt, 250_000); assert_eq!(state.companies[0].debt, 250_000);
assert!(state.companies[0].active); assert!(state.companies[0].active);
@ -3859,6 +3958,13 @@ mod tests {
state.service_state.annual_finance_last_actions.get(&32), state.service_state.annual_finance_last_actions.get(&32),
Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback) Some(&crate::RuntimeCompanyAnnualFinancePolicyAction::DeepDistressBankruptcyFallback)
); );
assert_eq!(
state
.service_state
.annual_finance_last_news_family_candidates
.get(&32),
Some(&"2881".to_string())
);
assert_eq!(state.companies[0].current_cash, 0); assert_eq!(state.companies[0].current_cash, 0);
assert_eq!(state.companies[0].debt, 125_000); assert_eq!(state.companies[0].debt, 125_000);
assert!(state.companies[0].active); assert!(state.companies[0].active);

View file

@ -174,6 +174,7 @@ pub struct RuntimeSummary {
pub selected_company_dividend_proposed_per_share_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_dividend_eligible_for_adjustment_branch: Option<bool>,
pub selected_company_annual_finance_policy_action: Option<String>, pub selected_company_annual_finance_policy_action: Option<String>,
pub selected_company_annual_finance_news_family_candidate: Option<String>,
pub selected_company_annual_finance_policy_creditor_pressure_bankruptcy_eligible: Option<bool>, pub selected_company_annual_finance_policy_creditor_pressure_bankruptcy_eligible: Option<bool>,
pub selected_company_annual_finance_policy_deep_distress_bankruptcy_fallback_eligible: pub selected_company_annual_finance_policy_deep_distress_bankruptcy_fallback_eligible:
Option<bool>, Option<bool>,
@ -808,6 +809,15 @@ impl RuntimeSummary {
runtime_company_annual_finance_policy_action_label(policy_state.action) runtime_company_annual_finance_policy_action_label(policy_state.action)
.to_string() .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_policy_creditor_pressure_bankruptcy_eligible: selected_company_annual_finance_policy_creditor_pressure_bankruptcy_eligible:
selected_company_annual_finance_policy_state selected_company_annual_finance_policy_state
.as_ref() .as_ref()
@ -3374,6 +3384,14 @@ mod tests {
service_state: RuntimeServiceState { service_state: RuntimeServiceState {
world_issue_opinion_base_terms_raw_i32: vec![0; 0x3b], world_issue_opinion_base_terms_raw_i32: vec![0; 0x3b],
chairman_personality_raw_u8: BTreeMap::from([(8, 20)]), 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(),
)]),
company_market_state: BTreeMap::from([( company_market_state: BTreeMap::from([(
14, 14,
crate::RuntimeCompanyMarketState { crate::RuntimeCompanyMarketState {
@ -3493,6 +3511,12 @@ mod tests {
summary.selected_company_stock_issue_eligible_for_double_tranche, summary.selected_company_stock_issue_eligible_for_double_tranche,
Some(true) Some(true)
); );
assert_eq!(
summary
.selected_company_annual_finance_news_family_candidate
.as_deref(),
Some("4053")
);
} }
#[test] #[test]