Rehost annual creditor pressure policy branch
This commit is contained in:
parent
e553275b2e
commit
64fc4a8488
8 changed files with 739 additions and 17 deletions
|
|
@ -89,7 +89,10 @@ bond table now also contributes both the largest live bond principal and the cho
|
||||||
highest-coupon live bond principal into owned company market and annual-finance state, so the
|
highest-coupon live bond principal into owned company market and annual-finance state, so the
|
||||||
stock-capital approval ladder can extend one rehosted owner-state surface instead of hunting
|
stock-capital approval ladder can extend one rehosted owner-state surface instead of hunting
|
||||||
another isolated finance leaf. A checked-in
|
another isolated finance leaf. A checked-in
|
||||||
The working rule on the remaining frontier is explicit now too: when a lane is still ambiguous, we
|
fixed-world finance-policy seam now also carries the raw stock, bond, bankruptcy, and dividend
|
||||||
|
policy bytes from the `0x32c8` save block, and the first annual creditor-pressure branch now runs
|
||||||
|
headlessly as a pure runtime reader over owned annual-finance state, support-adjusted share price,
|
||||||
|
and current world finance policy rather than as a notes-only atlas fragment. The working rule on the remaining frontier is explicit now too: when a lane is still ambiguous, we
|
||||||
should prefer rehosting the owning source state or the real reader/setter family rather than
|
should prefer rehosting the owning source state or the real reader/setter family rather than
|
||||||
guessing one more derived leaf field from nearby offsets. A checked-in
|
guessing one more derived leaf field from nearby offsets. A checked-in
|
||||||
`EventEffects` export now exists too in
|
`EventEffects` export now exists too in
|
||||||
|
|
|
||||||
|
|
@ -851,6 +851,38 @@ fn project_save_slice_components(
|
||||||
.world_issue_37_state
|
.world_issue_37_state
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|state| state.multiplier_value_f32_text.clone()),
|
.map(|state| state.multiplier_value_f32_text.clone()),
|
||||||
|
stock_issue_and_buyback_policy_raw_u8: save_slice
|
||||||
|
.world_finance_neighborhood_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|state| state.stock_policy_raw_u8),
|
||||||
|
bond_issue_and_repayment_policy_raw_u8: save_slice
|
||||||
|
.world_finance_neighborhood_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|state| state.bond_policy_raw_u8),
|
||||||
|
bankruptcy_policy_raw_u8: save_slice
|
||||||
|
.world_finance_neighborhood_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|state| state.bankruptcy_policy_raw_u8),
|
||||||
|
dividend_policy_raw_u8: save_slice
|
||||||
|
.world_finance_neighborhood_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|state| state.dividend_policy_raw_u8),
|
||||||
|
stock_issue_and_buyback_allowed: save_slice
|
||||||
|
.world_finance_neighborhood_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|state| state.stock_policy_raw_u8 == 0),
|
||||||
|
bond_issue_and_repayment_allowed: save_slice
|
||||||
|
.world_finance_neighborhood_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|state| state.bond_policy_raw_u8 == 0),
|
||||||
|
bankruptcy_allowed: save_slice
|
||||||
|
.world_finance_neighborhood_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|state| state.bankruptcy_policy_raw_u8 == 0),
|
||||||
|
dividend_adjustment_allowed: save_slice
|
||||||
|
.world_finance_neighborhood_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|state| state.dividend_policy_raw_u8 == 0),
|
||||||
finance_neighborhood_candidates: save_slice
|
finance_neighborhood_candidates: save_slice
|
||||||
.world_finance_neighborhood_state
|
.world_finance_neighborhood_state
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -5979,6 +6011,14 @@ mod tests {
|
||||||
absolute_counter_raw_hex: "0x00000003".to_string(),
|
absolute_counter_raw_hex: "0x00000003".to_string(),
|
||||||
absolute_counter_mirror_raw_u32: 4,
|
absolute_counter_mirror_raw_u32: 4,
|
||||||
absolute_counter_mirror_raw_hex: "0x00000004".to_string(),
|
absolute_counter_mirror_raw_hex: "0x00000004".to_string(),
|
||||||
|
stock_policy_raw_u8: 0,
|
||||||
|
stock_policy_raw_hex: "0x00".to_string(),
|
||||||
|
bond_policy_raw_u8: 1,
|
||||||
|
bond_policy_raw_hex: "0x01".to_string(),
|
||||||
|
bankruptcy_policy_raw_u8: 0,
|
||||||
|
bankruptcy_policy_raw_hex: "0x00".to_string(),
|
||||||
|
dividend_policy_raw_u8: 1,
|
||||||
|
dividend_policy_raw_hex: "0x01".to_string(),
|
||||||
labels: vec![
|
labels: vec![
|
||||||
"current_calendar_tuple_word".to_string(),
|
"current_calendar_tuple_word".to_string(),
|
||||||
"current_calendar_tuple_word_2".to_string(),
|
"current_calendar_tuple_word_2".to_string(),
|
||||||
|
|
@ -6263,6 +6303,35 @@ mod tests {
|
||||||
import.state.world_restore.issue_37_multiplier_raw_u32,
|
import.state.world_restore.issue_37_multiplier_raw_u32,
|
||||||
Some(0x3d75c28f)
|
Some(0x3d75c28f)
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
import
|
||||||
|
.state
|
||||||
|
.world_restore
|
||||||
|
.stock_issue_and_buyback_policy_raw_u8,
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
import
|
||||||
|
.state
|
||||||
|
.world_restore
|
||||||
|
.bond_issue_and_repayment_policy_raw_u8,
|
||||||
|
Some(1)
|
||||||
|
);
|
||||||
|
assert_eq!(import.state.world_restore.bankruptcy_policy_raw_u8, Some(0));
|
||||||
|
assert_eq!(import.state.world_restore.dividend_policy_raw_u8, Some(1));
|
||||||
|
assert_eq!(
|
||||||
|
import.state.world_restore.stock_issue_and_buyback_allowed,
|
||||||
|
Some(true)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
import.state.world_restore.bond_issue_and_repayment_allowed,
|
||||||
|
Some(false)
|
||||||
|
);
|
||||||
|
assert_eq!(import.state.world_restore.bankruptcy_allowed, Some(true));
|
||||||
|
assert_eq!(
|
||||||
|
import.state.world_restore.dividend_adjustment_allowed,
|
||||||
|
Some(false)
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
import
|
import
|
||||||
.state
|
.state
|
||||||
|
|
|
||||||
|
|
@ -52,12 +52,13 @@ pub use runtime::{
|
||||||
RUNTIME_WORLD_ISSUE_PRIME_RATE, RuntimeCargoCatalogEntry, RuntimeCargoClass,
|
RUNTIME_WORLD_ISSUE_PRIME_RATE, RuntimeCargoCatalogEntry, RuntimeCargoClass,
|
||||||
RuntimeCargoPriceTarget, RuntimeCargoProductionTarget, RuntimeChairmanMetric,
|
RuntimeCargoPriceTarget, RuntimeCargoProductionTarget, RuntimeChairmanMetric,
|
||||||
RuntimeChairmanProfile, RuntimeChairmanTarget, RuntimeCompany,
|
RuntimeChairmanProfile, RuntimeChairmanTarget, RuntimeCompany,
|
||||||
RuntimeCompanyAnnualFinanceState, RuntimeCompanyBondSlot, RuntimeCompanyConditionTestScope,
|
RuntimeCompanyAnnualCreditorPressureState, RuntimeCompanyAnnualFinanceState,
|
||||||
RuntimeCompanyControllerKind, RuntimeCompanyMarketMetric, RuntimeCompanyMarketState,
|
RuntimeCompanyBondSlot, RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind,
|
||||||
RuntimeCompanyMetric, RuntimeCompanyStatBandCandidate, RuntimeCompanyStatSelector,
|
RuntimeCompanyMarketMetric, RuntimeCompanyMarketState, RuntimeCompanyMetric,
|
||||||
RuntimeCompanyTarget, RuntimeCompanyTerritoryAccess, RuntimeCompanyTerritoryTrackPieceCount,
|
RuntimeCompanyStatBandCandidate, RuntimeCompanyStatSelector, RuntimeCompanyTarget,
|
||||||
RuntimeCondition, RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecord,
|
RuntimeCompanyTerritoryAccess, RuntimeCompanyTerritoryTrackPieceCount, RuntimeCondition,
|
||||||
RuntimeEventRecordTemplate, RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary,
|
RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate,
|
||||||
|
RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary,
|
||||||
RuntimePackedEventCompactControlSummary, RuntimePackedEventConditionRowSummary,
|
RuntimePackedEventCompactControlSummary, RuntimePackedEventConditionRowSummary,
|
||||||
RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventNegativeSentinelScopeSummary,
|
RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventNegativeSentinelScopeSummary,
|
||||||
RuntimePackedEventRecordSummary, RuntimePackedEventTextBandSummary, RuntimePlayer,
|
RuntimePackedEventRecordSummary, RuntimePackedEventTextBandSummary, RuntimePlayer,
|
||||||
|
|
@ -65,14 +66,18 @@ pub use runtime::{
|
||||||
RuntimeServiceState, RuntimeState, RuntimeTerritory, RuntimeTerritoryMetric,
|
RuntimeServiceState, RuntimeState, RuntimeTerritory, RuntimeTerritoryMetric,
|
||||||
RuntimeTerritoryTarget, RuntimeTrackMetric, RuntimeTrackPieceCounts, RuntimeTrain,
|
RuntimeTerritoryTarget, RuntimeTrackMetric, RuntimeTrackPieceCounts, RuntimeTrain,
|
||||||
RuntimeWorldFinanceNeighborhoodCandidate, RuntimeWorldIssueState, RuntimeWorldRestoreState,
|
RuntimeWorldFinanceNeighborhoodCandidate, RuntimeWorldIssueState, RuntimeWorldRestoreState,
|
||||||
runtime_company_annual_finance_state, runtime_company_assigned_share_pool,
|
runtime_company_annual_creditor_pressure_state, runtime_company_annual_finance_state,
|
||||||
runtime_company_average_live_bond_coupon, runtime_company_book_value_per_share,
|
runtime_company_assigned_share_pool, runtime_company_average_live_bond_coupon,
|
||||||
runtime_company_credit_rating, runtime_company_investor_confidence,
|
runtime_company_book_value_per_share, runtime_company_credit_rating,
|
||||||
runtime_company_management_attitude, runtime_company_market_value, runtime_company_prime_rate,
|
runtime_company_investor_confidence, runtime_company_management_attitude,
|
||||||
|
runtime_company_market_value, runtime_company_prime_rate,
|
||||||
runtime_company_recent_per_share_subscore, runtime_company_stat_value,
|
runtime_company_recent_per_share_subscore, runtime_company_stat_value,
|
||||||
runtime_company_stat_value_f64, runtime_company_unassigned_share_pool,
|
runtime_company_stat_value_f64, runtime_company_unassigned_share_pool,
|
||||||
|
runtime_world_annual_finance_mode_active, runtime_world_bankruptcy_allowed,
|
||||||
|
runtime_world_bond_issue_and_repayment_allowed, runtime_world_dividend_adjustment_allowed,
|
||||||
runtime_world_issue_opinion_multiplier, runtime_world_issue_opinion_term_sum_raw,
|
runtime_world_issue_opinion_multiplier, runtime_world_issue_opinion_term_sum_raw,
|
||||||
runtime_world_issue_state, runtime_world_prime_rate_baseline,
|
runtime_world_issue_state, runtime_world_prime_rate_baseline,
|
||||||
|
runtime_world_stock_issue_and_buyback_allowed,
|
||||||
};
|
};
|
||||||
pub use smp::{
|
pub use smp::{
|
||||||
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,
|
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,37 @@ pub struct RuntimeCompanyAnnualFinanceState {
|
||||||
pub linked_transit_latch: bool,
|
pub linked_transit_latch: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct RuntimeCompanyAnnualCreditorPressureState {
|
||||||
|
pub company_id: u32,
|
||||||
|
#[serde(default)]
|
||||||
|
pub annual_mode_active: Option<bool>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub bankruptcy_allowed: Option<bool>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub years_since_last_bankruptcy: Option<u32>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub years_since_founding: Option<u32>,
|
||||||
|
pub recent_bad_net_profit_year_count: u32,
|
||||||
|
#[serde(default)]
|
||||||
|
pub recent_peak_revenue: Option<i64>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub recent_three_year_net_profit_total: Option<i64>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub pressure_ladder_cash_floor: Option<i64>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub current_cash_plus_slot_12_total: Option<i64>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub support_adjusted_share_price_floor: Option<i64>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub support_adjusted_share_price_scalar: Option<i64>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub current_fuel_cost: Option<i64>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub current_fuel_cost_floor: Option<i64>,
|
||||||
|
pub eligible_for_bankruptcy_branch: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||||
pub struct RuntimeTrackPieceCounts {
|
pub struct RuntimeTrackPieceCounts {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
@ -1101,6 +1132,22 @@ pub struct RuntimeWorldRestoreState {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub issue_37_multiplier_value_f32_text: Option<String>,
|
pub issue_37_multiplier_value_f32_text: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
pub stock_issue_and_buyback_policy_raw_u8: Option<u8>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub bond_issue_and_repayment_policy_raw_u8: Option<u8>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub bankruptcy_policy_raw_u8: Option<u8>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub dividend_policy_raw_u8: Option<u8>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub stock_issue_and_buyback_allowed: Option<bool>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub bond_issue_and_repayment_allowed: Option<bool>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub bankruptcy_allowed: Option<bool>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub dividend_adjustment_allowed: Option<bool>,
|
||||||
|
#[serde(default)]
|
||||||
pub finance_neighborhood_candidates: Vec<RuntimeWorldFinanceNeighborhoodCandidate>,
|
pub finance_neighborhood_candidates: Vec<RuntimeWorldFinanceNeighborhoodCandidate>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub economic_tuning_mirror_raw_u32: Option<u32>,
|
pub economic_tuning_mirror_raw_u32: Option<u32>,
|
||||||
|
|
@ -2718,6 +2765,135 @@ pub fn runtime_company_average_live_bond_coupon(
|
||||||
Some(weighted_coupon_sum / total_principal as f64)
|
Some(weighted_coupon_sum / total_principal as f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn runtime_world_annual_finance_mode_active(state: &RuntimeState) -> Option<bool> {
|
||||||
|
Some(state.world_restore.partial_year_progress_raw_u8? == 0x0c)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn runtime_world_bankruptcy_allowed(state: &RuntimeState) -> Option<bool> {
|
||||||
|
Some(state.world_restore.bankruptcy_policy_raw_u8? == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn runtime_world_bond_issue_and_repayment_allowed(state: &RuntimeState) -> Option<bool> {
|
||||||
|
Some(state.world_restore.bond_issue_and_repayment_policy_raw_u8? == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn runtime_world_stock_issue_and_buyback_allowed(state: &RuntimeState) -> Option<bool> {
|
||||||
|
Some(state.world_restore.stock_issue_and_buyback_policy_raw_u8? == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn runtime_world_dividend_adjustment_allowed(state: &RuntimeState) -> Option<bool> {
|
||||||
|
Some(state.world_restore.dividend_policy_raw_u8? == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn runtime_company_annual_creditor_pressure_state(
|
||||||
|
state: &RuntimeState,
|
||||||
|
company_id: u32,
|
||||||
|
) -> Option<RuntimeCompanyAnnualCreditorPressureState> {
|
||||||
|
let annual_finance_state = runtime_company_annual_finance_state(state, company_id)?;
|
||||||
|
let current_cash_plus_slot_12_total =
|
||||||
|
runtime_company_control_transfer_stat_value_f64(state, company_id, 0x12)
|
||||||
|
.and_then(runtime_round_f64_to_i64)
|
||||||
|
.and_then(|slot_12| {
|
||||||
|
runtime_company_control_transfer_stat_value_f64(
|
||||||
|
state,
|
||||||
|
company_id,
|
||||||
|
RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
|
||||||
|
)
|
||||||
|
.and_then(runtime_round_f64_to_i64)
|
||||||
|
.map(|current_cash| current_cash + slot_12)
|
||||||
|
});
|
||||||
|
let support_adjusted_share_price_scalar =
|
||||||
|
runtime_company_support_adjusted_share_price_scalar_f64(state, company_id)
|
||||||
|
.and_then(runtime_round_f64_to_i64);
|
||||||
|
let current_fuel_cost = runtime_company_stat_value_f64(
|
||||||
|
state,
|
||||||
|
company_id,
|
||||||
|
RuntimeCompanyStatSelector {
|
||||||
|
family_id: RUNTIME_COMPANY_STAT_FAMILY_CONTROL_TRANSFER,
|
||||||
|
slot_id: 0x09,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.and_then(runtime_round_f64_to_i64);
|
||||||
|
let recent_bad_net_profit_year_count = annual_finance_state
|
||||||
|
.trailing_full_year_net_profits
|
||||||
|
.iter()
|
||||||
|
.take(3)
|
||||||
|
.filter(|value| **value < -10_000)
|
||||||
|
.count() as u32;
|
||||||
|
let recent_peak_revenue = annual_finance_state
|
||||||
|
.trailing_full_year_revenues
|
||||||
|
.iter()
|
||||||
|
.take(3)
|
||||||
|
.copied()
|
||||||
|
.max();
|
||||||
|
let recent_three_year_net_profit_total =
|
||||||
|
if annual_finance_state.trailing_full_year_net_profits.len() >= 3 {
|
||||||
|
Some(
|
||||||
|
annual_finance_state
|
||||||
|
.trailing_full_year_net_profits
|
||||||
|
.iter()
|
||||||
|
.take(3)
|
||||||
|
.sum::<i64>(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let pressure_ladder_cash_floor = recent_peak_revenue.map(|revenue| {
|
||||||
|
if revenue < 120_000 {
|
||||||
|
-600_000
|
||||||
|
} else if revenue < 230_000 {
|
||||||
|
-1_100_000
|
||||||
|
} else if revenue < 340_000 {
|
||||||
|
-1_600_000
|
||||||
|
} else {
|
||||||
|
-2_000_000
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let support_adjusted_share_price_floor = Some(if recent_bad_net_profit_year_count == 3 {
|
||||||
|
20
|
||||||
|
} else {
|
||||||
|
15
|
||||||
|
});
|
||||||
|
let current_fuel_cost_floor = pressure_ladder_cash_floor.map(|floor| floor * 8 / 100);
|
||||||
|
let eligible_for_bankruptcy_branch = runtime_world_annual_finance_mode_active(state)
|
||||||
|
== Some(true)
|
||||||
|
&& runtime_world_bankruptcy_allowed(state) == Some(true)
|
||||||
|
&& annual_finance_state
|
||||||
|
.years_since_last_bankruptcy
|
||||||
|
.is_some_and(|years| years >= 13)
|
||||||
|
&& annual_finance_state
|
||||||
|
.years_since_founding
|
||||||
|
.is_some_and(|years| years >= 4)
|
||||||
|
&& recent_bad_net_profit_year_count >= 2
|
||||||
|
&& current_cash_plus_slot_12_total
|
||||||
|
.zip(pressure_ladder_cash_floor)
|
||||||
|
.is_some_and(|(value, floor)| value <= floor)
|
||||||
|
&& support_adjusted_share_price_scalar
|
||||||
|
.zip(support_adjusted_share_price_floor)
|
||||||
|
.is_some_and(|(value, floor)| value >= floor)
|
||||||
|
&& current_fuel_cost
|
||||||
|
.zip(current_fuel_cost_floor)
|
||||||
|
.is_some_and(|(value, floor)| value <= floor)
|
||||||
|
&& recent_three_year_net_profit_total.is_some_and(|value| value <= -60_000);
|
||||||
|
Some(RuntimeCompanyAnnualCreditorPressureState {
|
||||||
|
company_id,
|
||||||
|
annual_mode_active: runtime_world_annual_finance_mode_active(state),
|
||||||
|
bankruptcy_allowed: runtime_world_bankruptcy_allowed(state),
|
||||||
|
years_since_last_bankruptcy: annual_finance_state.years_since_last_bankruptcy,
|
||||||
|
years_since_founding: annual_finance_state.years_since_founding,
|
||||||
|
recent_bad_net_profit_year_count,
|
||||||
|
recent_peak_revenue,
|
||||||
|
recent_three_year_net_profit_total,
|
||||||
|
pressure_ladder_cash_floor,
|
||||||
|
current_cash_plus_slot_12_total,
|
||||||
|
support_adjusted_share_price_floor,
|
||||||
|
support_adjusted_share_price_scalar,
|
||||||
|
current_fuel_cost,
|
||||||
|
current_fuel_cost_floor,
|
||||||
|
eligible_for_bankruptcy_branch,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn runtime_world_absolute_counter(state: &RuntimeState) -> Option<u32> {
|
pub fn runtime_world_absolute_counter(state: &RuntimeState) -> Option<u32> {
|
||||||
state.world_restore.absolute_counter_raw_u32
|
state.world_restore.absolute_counter_raw_u32
|
||||||
}
|
}
|
||||||
|
|
@ -3522,6 +3698,14 @@ mod tests {
|
||||||
issue_3a_value: None,
|
issue_3a_value: None,
|
||||||
issue_37_multiplier_raw_u32: None,
|
issue_37_multiplier_raw_u32: None,
|
||||||
issue_37_multiplier_value_f32_text: None,
|
issue_37_multiplier_value_f32_text: None,
|
||||||
|
stock_issue_and_buyback_policy_raw_u8: None,
|
||||||
|
bond_issue_and_repayment_policy_raw_u8: None,
|
||||||
|
bankruptcy_policy_raw_u8: None,
|
||||||
|
dividend_policy_raw_u8: None,
|
||||||
|
stock_issue_and_buyback_allowed: None,
|
||||||
|
bond_issue_and_repayment_allowed: None,
|
||||||
|
bankruptcy_allowed: None,
|
||||||
|
dividend_adjustment_allowed: None,
|
||||||
finance_neighborhood_candidates: Vec::new(),
|
finance_neighborhood_candidates: Vec::new(),
|
||||||
economic_tuning_mirror_raw_u32: None,
|
economic_tuning_mirror_raw_u32: None,
|
||||||
economic_tuning_mirror_value_f32_text: None,
|
economic_tuning_mirror_value_f32_text: None,
|
||||||
|
|
@ -4859,7 +5043,7 @@ mod tests {
|
||||||
fn reads_grounded_company_stat_family_slots_from_runtime_state() {
|
fn reads_grounded_company_stat_family_slots_from_runtime_state() {
|
||||||
let mut year_stat_family_qword_bits = vec![
|
let mut year_stat_family_qword_bits = vec![
|
||||||
0u64;
|
0u64;
|
||||||
(RUNTIME_COMPANY_STAT_SLOT_COUNT * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
|
((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
|
||||||
as usize
|
as usize
|
||||||
];
|
];
|
||||||
year_stat_family_qword_bits[(0x12 * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize] =
|
year_stat_family_qword_bits[(0x12 * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize] =
|
||||||
|
|
@ -5271,7 +5455,7 @@ mod tests {
|
||||||
fn reads_year_relative_company_stat_family_from_saved_market_matrix() {
|
fn reads_year_relative_company_stat_family_from_saved_market_matrix() {
|
||||||
let mut year_stat_family_qword_bits = vec![
|
let mut year_stat_family_qword_bits = vec![
|
||||||
0u64;
|
0u64;
|
||||||
(RUNTIME_COMPANY_STAT_SLOT_COUNT * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
|
((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
|
||||||
as usize
|
as usize
|
||||||
];
|
];
|
||||||
let write_year_value = |bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
|
let write_year_value = |bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
|
||||||
|
|
@ -6626,6 +6810,132 @@ mod tests {
|
||||||
assert_eq!(runtime_company_annual_finance_state(&state, 99), None);
|
assert_eq!(runtime_company_annual_finance_state(&state, 99), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn derives_annual_creditor_pressure_from_rehosted_finance_owner_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_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
|
||||||
|
let index = (slot_id * 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 * 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: 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: 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 {
|
||||||
|
founding_year: 1841,
|
||||||
|
last_bankruptcy_year: 1832,
|
||||||
|
cached_share_price_raw_u32: 25.0f32.to_bits(),
|
||||||
|
year_stat_family_qword_bits,
|
||||||
|
..RuntimeCompanyMarketState::default()
|
||||||
|
},
|
||||||
|
)]),
|
||||||
|
..RuntimeServiceState::default()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(runtime_world_annual_finance_mode_active(&state), Some(true));
|
||||||
|
assert_eq!(runtime_world_bankruptcy_allowed(&state), Some(true));
|
||||||
|
let pressure_state = runtime_company_annual_creditor_pressure_state(&state, 7)
|
||||||
|
.expect("creditor pressure state");
|
||||||
|
assert_eq!(pressure_state.recent_bad_net_profit_year_count, 3);
|
||||||
|
assert_eq!(pressure_state.recent_peak_revenue, Some(100_000));
|
||||||
|
assert_eq!(
|
||||||
|
pressure_state.recent_three_year_net_profit_total,
|
||||||
|
Some(-65_000)
|
||||||
|
);
|
||||||
|
assert_eq!(pressure_state.pressure_ladder_cash_floor, Some(-600_000));
|
||||||
|
assert_eq!(
|
||||||
|
pressure_state.current_cash_plus_slot_12_total,
|
||||||
|
Some(-700_000)
|
||||||
|
);
|
||||||
|
assert_eq!(pressure_state.support_adjusted_share_price_floor, Some(20));
|
||||||
|
assert_eq!(pressure_state.support_adjusted_share_price_scalar, Some(25));
|
||||||
|
assert_eq!(pressure_state.current_fuel_cost, Some(-50_000));
|
||||||
|
assert_eq!(pressure_state.current_fuel_cost_floor, Some(-48_000));
|
||||||
|
assert!(pressure_state.eligible_for_bankruptcy_branch);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reads_company_market_metrics_from_annual_finance_reader() {
|
fn reads_company_market_metrics_from_annual_finance_reader() {
|
||||||
let current_issue_calendar_word = 0x0101_0726;
|
let current_issue_calendar_word = 0x0101_0726;
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,10 @@ const RT3_SAVE_WORLD_BLOCK_ISSUE_OPINION_TERM_COUNT: usize = 0x3b;
|
||||||
const RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_SELECTOR_RELATIVE_OFFSET: usize = 0x83;
|
const RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_SELECTOR_RELATIVE_OFFSET: usize = 0x83;
|
||||||
const RT3_SAVE_WORLD_BLOCK_CAMPAIGN_OVERRIDE_FLAG_RELATIVE_OFFSET: usize = 0xc1;
|
const RT3_SAVE_WORLD_BLOCK_CAMPAIGN_OVERRIDE_FLAG_RELATIVE_OFFSET: usize = 0xc1;
|
||||||
const RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_RELATIVE_OFFSET: usize = 0x0bbf;
|
const RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_RELATIVE_OFFSET: usize = 0x0bbf;
|
||||||
|
const RT3_SAVE_WORLD_BLOCK_STOCK_POLICY_RELATIVE_OFFSET: usize = 0x4a83;
|
||||||
|
const RT3_SAVE_WORLD_BLOCK_BOND_POLICY_RELATIVE_OFFSET: usize = 0x4a87;
|
||||||
|
const RT3_SAVE_WORLD_BLOCK_BANKRUPTCY_POLICY_RELATIVE_OFFSET: usize = 0x4a8b;
|
||||||
|
const RT3_SAVE_WORLD_BLOCK_DIVIDEND_POLICY_RELATIVE_OFFSET: usize = 0x4a8f;
|
||||||
const RT3_SAVE_WORLD_BLOCK_ECONOMIC_TUNING_MIRROR_RELATIVE_OFFSET: usize = 0x0bda;
|
const RT3_SAVE_WORLD_BLOCK_ECONOMIC_TUNING_MIRROR_RELATIVE_OFFSET: usize = 0x0bda;
|
||||||
const RT3_SAVE_WORLD_BLOCK_ECONOMIC_TUNING_PRIMARY_RELATIVE_OFFSETS: [usize; 6] =
|
const RT3_SAVE_WORLD_BLOCK_ECONOMIC_TUNING_PRIMARY_RELATIVE_OFFSETS: [usize; 6] =
|
||||||
[0x0bde, 0x0be2, 0x0be6, 0x0bea, 0x0bee, 0x0bf2];
|
[0x0bde, 0x0be2, 0x0be6, 0x0bea, 0x0bee, 0x0bf2];
|
||||||
|
|
@ -1572,6 +1576,14 @@ pub struct SmpSaveWorldFinanceNeighborhoodProbe {
|
||||||
pub current_calendar_tuple_word_2_lane: SmpSaveDwordCandidate,
|
pub current_calendar_tuple_word_2_lane: SmpSaveDwordCandidate,
|
||||||
pub absolute_counter_lane: SmpSaveDwordCandidate,
|
pub absolute_counter_lane: SmpSaveDwordCandidate,
|
||||||
pub absolute_counter_mirror_lane: SmpSaveDwordCandidate,
|
pub absolute_counter_mirror_lane: SmpSaveDwordCandidate,
|
||||||
|
pub stock_policy_raw_u8: u8,
|
||||||
|
pub stock_policy_raw_hex: String,
|
||||||
|
pub bond_policy_raw_u8: u8,
|
||||||
|
pub bond_policy_raw_hex: String,
|
||||||
|
pub bankruptcy_policy_raw_u8: u8,
|
||||||
|
pub bankruptcy_policy_raw_hex: String,
|
||||||
|
pub dividend_policy_raw_u8: u8,
|
||||||
|
pub dividend_policy_raw_hex: String,
|
||||||
pub dword_candidates: Vec<SmpSaveDwordCandidate>,
|
pub dword_candidates: Vec<SmpSaveDwordCandidate>,
|
||||||
pub evidence: Vec<String>,
|
pub evidence: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
@ -2256,6 +2268,14 @@ pub struct SmpLoadedWorldFinanceNeighborhoodState {
|
||||||
pub absolute_counter_raw_hex: String,
|
pub absolute_counter_raw_hex: String,
|
||||||
pub absolute_counter_mirror_raw_u32: u32,
|
pub absolute_counter_mirror_raw_u32: u32,
|
||||||
pub absolute_counter_mirror_raw_hex: String,
|
pub absolute_counter_mirror_raw_hex: String,
|
||||||
|
pub stock_policy_raw_u8: u8,
|
||||||
|
pub stock_policy_raw_hex: String,
|
||||||
|
pub bond_policy_raw_u8: u8,
|
||||||
|
pub bond_policy_raw_hex: String,
|
||||||
|
pub bankruptcy_policy_raw_u8: u8,
|
||||||
|
pub bankruptcy_policy_raw_hex: String,
|
||||||
|
pub dividend_policy_raw_u8: u8,
|
||||||
|
pub dividend_policy_raw_hex: String,
|
||||||
pub labels: Vec<String>,
|
pub labels: Vec<String>,
|
||||||
pub relative_offsets: Vec<usize>,
|
pub relative_offsets: Vec<usize>,
|
||||||
pub relative_offset_hex: Vec<String>,
|
pub relative_offset_hex: Vec<String>,
|
||||||
|
|
@ -3500,6 +3520,14 @@ fn derive_loaded_world_finance_neighborhood_state_from_probe(
|
||||||
absolute_counter_raw_hex: probe.absolute_counter_lane.raw_u32_hex.clone(),
|
absolute_counter_raw_hex: probe.absolute_counter_lane.raw_u32_hex.clone(),
|
||||||
absolute_counter_mirror_raw_u32: probe.absolute_counter_mirror_lane.raw_u32,
|
absolute_counter_mirror_raw_u32: probe.absolute_counter_mirror_lane.raw_u32,
|
||||||
absolute_counter_mirror_raw_hex: probe.absolute_counter_mirror_lane.raw_u32_hex.clone(),
|
absolute_counter_mirror_raw_hex: probe.absolute_counter_mirror_lane.raw_u32_hex.clone(),
|
||||||
|
stock_policy_raw_u8: probe.stock_policy_raw_u8,
|
||||||
|
stock_policy_raw_hex: probe.stock_policy_raw_hex.clone(),
|
||||||
|
bond_policy_raw_u8: probe.bond_policy_raw_u8,
|
||||||
|
bond_policy_raw_hex: probe.bond_policy_raw_hex.clone(),
|
||||||
|
bankruptcy_policy_raw_u8: probe.bankruptcy_policy_raw_u8,
|
||||||
|
bankruptcy_policy_raw_hex: probe.bankruptcy_policy_raw_hex.clone(),
|
||||||
|
dividend_policy_raw_u8: probe.dividend_policy_raw_u8,
|
||||||
|
dividend_policy_raw_hex: probe.dividend_policy_raw_hex.clone(),
|
||||||
labels: probe
|
labels: probe
|
||||||
.dword_candidates
|
.dword_candidates
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -9100,6 +9128,22 @@ fn parse_save_world_finance_neighborhood_probe(
|
||||||
"absolute_calendar_counter_mirror",
|
"absolute_calendar_counter_mirror",
|
||||||
RT3_SAVE_WORLD_BLOCK_ABSOLUTE_COUNTER_MIRROR_RELATIVE_OFFSET,
|
RT3_SAVE_WORLD_BLOCK_ABSOLUTE_COUNTER_MIRROR_RELATIVE_OFFSET,
|
||||||
)?;
|
)?;
|
||||||
|
let stock_policy_raw_u8 = read_u8_at(
|
||||||
|
bytes,
|
||||||
|
payload_offset + RT3_SAVE_WORLD_BLOCK_STOCK_POLICY_RELATIVE_OFFSET,
|
||||||
|
)?;
|
||||||
|
let bond_policy_raw_u8 = read_u8_at(
|
||||||
|
bytes,
|
||||||
|
payload_offset + RT3_SAVE_WORLD_BLOCK_BOND_POLICY_RELATIVE_OFFSET,
|
||||||
|
)?;
|
||||||
|
let bankruptcy_policy_raw_u8 = read_u8_at(
|
||||||
|
bytes,
|
||||||
|
payload_offset + RT3_SAVE_WORLD_BLOCK_BANKRUPTCY_POLICY_RELATIVE_OFFSET,
|
||||||
|
)?;
|
||||||
|
let dividend_policy_raw_u8 = read_u8_at(
|
||||||
|
bytes,
|
||||||
|
payload_offset + RT3_SAVE_WORLD_BLOCK_DIVIDEND_POLICY_RELATIVE_OFFSET,
|
||||||
|
)?;
|
||||||
let dword_candidates =
|
let dword_candidates =
|
||||||
build_save_world_finance_neighborhood_candidates(bytes, payload_offset)?;
|
build_save_world_finance_neighborhood_candidates(bytes, payload_offset)?;
|
||||||
|
|
||||||
|
|
@ -9119,6 +9163,14 @@ fn parse_save_world_finance_neighborhood_probe(
|
||||||
current_calendar_tuple_word_2_lane,
|
current_calendar_tuple_word_2_lane,
|
||||||
absolute_counter_lane,
|
absolute_counter_lane,
|
||||||
absolute_counter_mirror_lane,
|
absolute_counter_mirror_lane,
|
||||||
|
stock_policy_raw_u8,
|
||||||
|
stock_policy_raw_hex: format!("0x{stock_policy_raw_u8:02x}"),
|
||||||
|
bond_policy_raw_u8,
|
||||||
|
bond_policy_raw_hex: format!("0x{bond_policy_raw_u8:02x}"),
|
||||||
|
bankruptcy_policy_raw_u8,
|
||||||
|
bankruptcy_policy_raw_hex: format!("0x{bankruptcy_policy_raw_u8:02x}"),
|
||||||
|
dividend_policy_raw_u8,
|
||||||
|
dividend_policy_raw_hex: format!("0x{dividend_policy_raw_u8:02x}"),
|
||||||
dword_candidates,
|
dword_candidates,
|
||||||
evidence: vec![
|
evidence: vec![
|
||||||
format!(
|
format!(
|
||||||
|
|
@ -9133,6 +9185,13 @@ fn parse_save_world_finance_neighborhood_probe(
|
||||||
RT3_SAVE_WORLD_BLOCK_CURRENT_CALENDAR_TUPLE_WORD_2_RELATIVE_OFFSET,
|
RT3_SAVE_WORLD_BLOCK_CURRENT_CALENDAR_TUPLE_WORD_2_RELATIVE_OFFSET,
|
||||||
RT3_SAVE_WORLD_BLOCK_ABSOLUTE_COUNTER_RELATIVE_OFFSET
|
RT3_SAVE_WORLD_BLOCK_ABSOLUTE_COUNTER_RELATIVE_OFFSET
|
||||||
),
|
),
|
||||||
|
format!(
|
||||||
|
"payload +0x{:x}/+0x{:x}/+0x{:x}/+0x{:x} carry the stock, bond, bankruptcy, and dividend finance-policy bytes mirrored from scenario offsets 0x4a87/0x4a8b/0x4a8f/0x4a93",
|
||||||
|
RT3_SAVE_WORLD_BLOCK_STOCK_POLICY_RELATIVE_OFFSET,
|
||||||
|
RT3_SAVE_WORLD_BLOCK_BOND_POLICY_RELATIVE_OFFSET,
|
||||||
|
RT3_SAVE_WORLD_BLOCK_BANKRUPTCY_POLICY_RELATIVE_OFFSET,
|
||||||
|
RT3_SAVE_WORLD_BLOCK_DIVIDEND_POLICY_RELATIVE_OFFSET
|
||||||
|
),
|
||||||
"finance-neighborhood candidates cover the fixed dword strip around the grounded world calendar tuple, absolute-counter, selection-context, and issue-0x37 lanes so broader finance reader closure can build on one rehosted owner surface.".to_string(),
|
"finance-neighborhood candidates cover the fixed dword strip around the grounded world calendar tuple, absolute-counter, selection-context, and issue-0x37 lanes so broader finance reader closure can build on one rehosted owner surface.".to_string(),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
@ -15868,6 +15927,10 @@ mod tests {
|
||||||
bytes[payload_offset + relative_offset..payload_offset + relative_offset + 4]
|
bytes[payload_offset + relative_offset..payload_offset + relative_offset + 4]
|
||||||
.copy_from_slice(&((index as u32) + 1).to_le_bytes());
|
.copy_from_slice(&((index as u32) + 1).to_le_bytes());
|
||||||
}
|
}
|
||||||
|
bytes[payload_offset + RT3_SAVE_WORLD_BLOCK_STOCK_POLICY_RELATIVE_OFFSET] = 1;
|
||||||
|
bytes[payload_offset + RT3_SAVE_WORLD_BLOCK_BOND_POLICY_RELATIVE_OFFSET] = 2;
|
||||||
|
bytes[payload_offset + RT3_SAVE_WORLD_BLOCK_BANKRUPTCY_POLICY_RELATIVE_OFFSET] = 3;
|
||||||
|
bytes[payload_offset + RT3_SAVE_WORLD_BLOCK_DIVIDEND_POLICY_RELATIVE_OFFSET] = 4;
|
||||||
let next_chunk_offset = payload_offset + RT3_SAVE_WORLD_BLOCK_LEN;
|
let next_chunk_offset = payload_offset + RT3_SAVE_WORLD_BLOCK_LEN;
|
||||||
bytes[next_chunk_offset..next_chunk_offset + 4]
|
bytes[next_chunk_offset..next_chunk_offset + 4]
|
||||||
.copy_from_slice(&RT3_SAVE_WORLD_BLOCK_NEXT_CHUNK_TAG.to_le_bytes());
|
.copy_from_slice(&RT3_SAVE_WORLD_BLOCK_NEXT_CHUNK_TAG.to_le_bytes());
|
||||||
|
|
@ -15897,6 +15960,14 @@ mod tests {
|
||||||
assert_eq!(probe.packed_year_word_raw_hex, "0x0001");
|
assert_eq!(probe.packed_year_word_raw_hex, "0x0001");
|
||||||
assert_eq!(probe.partial_year_progress_raw_u8, 0);
|
assert_eq!(probe.partial_year_progress_raw_u8, 0);
|
||||||
assert_eq!(probe.partial_year_progress_raw_hex, "0x00");
|
assert_eq!(probe.partial_year_progress_raw_hex, "0x00");
|
||||||
|
assert_eq!(probe.stock_policy_raw_u8, 1);
|
||||||
|
assert_eq!(probe.stock_policy_raw_hex, "0x01");
|
||||||
|
assert_eq!(probe.bond_policy_raw_u8, 2);
|
||||||
|
assert_eq!(probe.bond_policy_raw_hex, "0x02");
|
||||||
|
assert_eq!(probe.bankruptcy_policy_raw_u8, 3);
|
||||||
|
assert_eq!(probe.bankruptcy_policy_raw_hex, "0x03");
|
||||||
|
assert_eq!(probe.dividend_policy_raw_u8, 4);
|
||||||
|
assert_eq!(probe.dividend_policy_raw_hex, "0x04");
|
||||||
assert_eq!(probe.current_calendar_tuple_word_lane.value_i32, 1);
|
assert_eq!(probe.current_calendar_tuple_word_lane.value_i32, 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
probe.current_calendar_tuple_word_2_lane.relative_offset_hex,
|
probe.current_calendar_tuple_word_2_lane.relative_offset_hex,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CalendarPoint, RuntimeState, runtime_company_annual_finance_state,
|
CalendarPoint, RuntimeState, runtime_company_annual_creditor_pressure_state,
|
||||||
runtime_company_unassigned_share_pool,
|
runtime_company_annual_finance_state, runtime_company_unassigned_share_pool,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn raw_u32_to_f32_text(raw: u32) -> String {
|
fn raw_u32_to_f32_text(raw: u32) -> String {
|
||||||
|
|
@ -50,6 +50,14 @@ pub struct RuntimeSummary {
|
||||||
pub world_restore_issue_3a_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_raw_u32: Option<u32>,
|
||||||
pub world_restore_issue_37_multiplier_value_f32_text: Option<String>,
|
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_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_count: usize,
|
||||||
pub world_restore_finance_neighborhood_labels: Vec<String>,
|
pub world_restore_finance_neighborhood_labels: Vec<String>,
|
||||||
pub world_restore_economic_tuning_mirror_raw_u32: Option<u32>,
|
pub world_restore_economic_tuning_mirror_raw_u32: Option<u32>,
|
||||||
|
|
@ -87,6 +95,16 @@ pub struct RuntimeSummary {
|
||||||
pub selected_company_current_issue_age_absolute_counter_delta: Option<i64>,
|
pub selected_company_current_issue_age_absolute_counter_delta: Option<i64>,
|
||||||
pub selected_company_chairman_bonus_year: Option<u32>,
|
pub selected_company_chairman_bonus_year: Option<u32>,
|
||||||
pub selected_company_chairman_bonus_amount: Option<i32>,
|
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 player_count: usize,
|
pub player_count: usize,
|
||||||
pub chairman_profile_count: usize,
|
pub chairman_profile_count: usize,
|
||||||
pub active_chairman_profile_count: usize,
|
pub active_chairman_profile_count: usize,
|
||||||
|
|
@ -176,6 +194,10 @@ impl RuntimeSummary {
|
||||||
let selected_company_annual_finance_state = state
|
let selected_company_annual_finance_state = state
|
||||||
.selected_company_id
|
.selected_company_id
|
||||||
.and_then(|company_id| runtime_company_annual_finance_state(state, 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)
|
||||||
|
});
|
||||||
Self {
|
Self {
|
||||||
calendar: state.calendar,
|
calendar: state.calendar,
|
||||||
calendar_projection_source: state.metadata.get("save_slice.calendar_source").cloned(),
|
calendar_projection_source: state.metadata.get("save_slice.calendar_source").cloned(),
|
||||||
|
|
@ -255,6 +277,24 @@ impl RuntimeSummary {
|
||||||
.world_restore
|
.world_restore
|
||||||
.issue_37_multiplier_value_f32_text
|
.issue_37_multiplier_value_f32_text
|
||||||
.clone(),
|
.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_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_count: state
|
||||||
.world_restore
|
.world_restore
|
||||||
.finance_neighborhood_candidates
|
.finance_neighborhood_candidates
|
||||||
|
|
@ -372,6 +412,45 @@ impl RuntimeSummary {
|
||||||
selected_company_chairman_bonus_amount: selected_company_market_state
|
selected_company_chairman_bonus_amount: selected_company_market_state
|
||||||
.map(|market_state| market_state.chairman_bonus_amount)
|
.map(|market_state| market_state.chairman_bonus_amount)
|
||||||
.filter(|amount| *amount != 0),
|
.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),
|
||||||
player_count: state.players.len(),
|
player_count: state.players.len(),
|
||||||
chairman_profile_count: state.chairman_profiles.len(),
|
chairman_profile_count: state.chairman_profiles.len(),
|
||||||
active_chairman_profile_count: state
|
active_chairman_profile_count: state
|
||||||
|
|
@ -1217,6 +1296,14 @@ mod tests {
|
||||||
issue_3a_value: Some(4),
|
issue_3a_value: Some(4),
|
||||||
issue_37_multiplier_raw_u32: Some(0x3d75c28f),
|
issue_37_multiplier_raw_u32: Some(0x3d75c28f),
|
||||||
issue_37_multiplier_value_f32_text: Some("0.06".to_string()),
|
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_raw_u32: Some(0x3f46dff5),
|
||||||
economic_tuning_mirror_value_f32_text: Some("0.7766201".to_string()),
|
economic_tuning_mirror_value_f32_text: Some("0.7766201".to_string()),
|
||||||
economic_tuning_lane_raw_u32: vec![
|
economic_tuning_lane_raw_u32: vec![
|
||||||
|
|
@ -1301,6 +1388,29 @@ mod tests {
|
||||||
summary.world_restore_issue_37_multiplier_raw_u32,
|
summary.world_restore_issue_37_multiplier_raw_u32,
|
||||||
Some(0x3d75c28f)
|
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!(
|
assert_eq!(
|
||||||
summary
|
summary
|
||||||
.world_restore_issue_37_multiplier_value_f32_text
|
.world_restore_issue_37_multiplier_value_f32_text
|
||||||
|
|
@ -2177,4 +2287,153 @@ mod tests {
|
||||||
assert_eq!(summary.selected_company_chairman_bonus_year, Some(1842));
|
assert_eq!(summary.selected_company_chairman_bonus_year, Some(1842));
|
||||||
assert_eq!(summary.selected_company_chairman_bonus_amount, Some(750));
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,9 @@ The highest-value next passes are now:
|
||||||
and last bankruptcy for later annual finance-policy rehosting; live bond-slot count now travels through that same owned annual-finance
|
and last bankruptcy for later annual finance-policy rehosting; live bond-slot count now travels through that same owned annual-finance
|
||||||
state for the stock-capital branch gate, and the grounded bond table now also contributes both
|
state for the stock-capital branch gate, and the grounded bond table now also contributes both
|
||||||
the largest live bond principal and the chosen highest-coupon live bond principal into that same
|
the largest live bond principal and the chosen highest-coupon live bond principal into that same
|
||||||
owner-state surface
|
owner-state surface; the same fixed-world save block now also carries the raw stock, bond,
|
||||||
|
bankruptcy, and dividend finance-policy bytes, and the first annual creditor-pressure branch now
|
||||||
|
executes as a pure runtime reader over that owner state instead of remaining atlas-only
|
||||||
- the project rule on the remaining closure work is now explicit too: when one runtime-facing field
|
- the project rule on the remaining closure work is now explicit too: when one runtime-facing field
|
||||||
is still ambiguous, prefer rehosting the owning source state or real reader/setter family first
|
is still ambiguous, prefer rehosting the owning source state or real reader/setter family first
|
||||||
instead of guessing another derived leaf field from neighboring raw offsets
|
instead of guessing another derived leaf field from neighboring raw offsets
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,10 @@ owned company market and annual-finance state, matching the stock-capital branch
|
||||||
at least two live bonds. The same grounded bond table now also contributes both the largest live
|
at least two live bonds. The same grounded bond table now also contributes both the largest live
|
||||||
bond principal and the chosen highest-coupon live bond principal into owned company market and
|
bond principal and the chosen highest-coupon live bond principal into owned company market and
|
||||||
annual-finance state, so later stock-capital gates can extend a rehosted owner-state seam instead
|
annual-finance state, so later stock-capital gates can extend a rehosted owner-state seam instead
|
||||||
of guessing another finance leaf.
|
of guessing another finance leaf. The same fixed-world save block now also carries the raw stock,
|
||||||
|
bond, bankruptcy, and dividend finance-policy bytes, and the earliest annual creditor-pressure
|
||||||
|
bankruptcy branch now runs as a pure runtime reader over owned annual-finance state, support-
|
||||||
|
adjusted share price, and those policy bytes rather than staying in atlas prose only.
|
||||||
|
|
||||||
## Why This Boundary
|
## Why This Boundary
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue