Rehost annual deep-distress bankruptcy fallback
This commit is contained in:
parent
64fc4a8488
commit
5e19e8985a
6 changed files with 354 additions and 16 deletions
|
|
@ -92,7 +92,10 @@ another isolated finance leaf. A checked-in
|
|||
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
|
||||
and current world finance policy rather than as a notes-only atlas fragment. The later deep-
|
||||
distress bankruptcy fallback is now rehosted on that same owner surface too, using the save-native
|
||||
cash reader seam plus the first three trailing net-profit years instead of another ad hoc probe.
|
||||
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
|
||||
guessing one more derived leaf field from nearby offsets. A checked-in
|
||||
`EventEffects` export now exists too in
|
||||
|
|
|
|||
|
|
@ -52,13 +52,13 @@ pub use runtime::{
|
|||
RUNTIME_WORLD_ISSUE_PRIME_RATE, RuntimeCargoCatalogEntry, RuntimeCargoClass,
|
||||
RuntimeCargoPriceTarget, RuntimeCargoProductionTarget, RuntimeChairmanMetric,
|
||||
RuntimeChairmanProfile, RuntimeChairmanTarget, RuntimeCompany,
|
||||
RuntimeCompanyAnnualCreditorPressureState, RuntimeCompanyAnnualFinanceState,
|
||||
RuntimeCompanyBondSlot, RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind,
|
||||
RuntimeCompanyMarketMetric, RuntimeCompanyMarketState, RuntimeCompanyMetric,
|
||||
RuntimeCompanyStatBandCandidate, RuntimeCompanyStatSelector, RuntimeCompanyTarget,
|
||||
RuntimeCompanyTerritoryAccess, RuntimeCompanyTerritoryTrackPieceCount, RuntimeCondition,
|
||||
RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate,
|
||||
RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary,
|
||||
RuntimeCompanyAnnualCreditorPressureState, RuntimeCompanyAnnualDeepDistressState,
|
||||
RuntimeCompanyAnnualFinanceState, RuntimeCompanyBondSlot, RuntimeCompanyConditionTestScope,
|
||||
RuntimeCompanyControllerKind, RuntimeCompanyMarketMetric, RuntimeCompanyMarketState,
|
||||
RuntimeCompanyMetric, RuntimeCompanyStatBandCandidate, RuntimeCompanyStatSelector,
|
||||
RuntimeCompanyTarget, RuntimeCompanyTerritoryAccess, RuntimeCompanyTerritoryTrackPieceCount,
|
||||
RuntimeCondition, RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecord,
|
||||
RuntimeEventRecordTemplate, RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary,
|
||||
RuntimePackedEventCompactControlSummary, RuntimePackedEventConditionRowSummary,
|
||||
RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventNegativeSentinelScopeSummary,
|
||||
RuntimePackedEventRecordSummary, RuntimePackedEventTextBandSummary, RuntimePlayer,
|
||||
|
|
@ -66,11 +66,11 @@ pub use runtime::{
|
|||
RuntimeServiceState, RuntimeState, RuntimeTerritory, RuntimeTerritoryMetric,
|
||||
RuntimeTerritoryTarget, RuntimeTrackMetric, RuntimeTrackPieceCounts, RuntimeTrain,
|
||||
RuntimeWorldFinanceNeighborhoodCandidate, RuntimeWorldIssueState, RuntimeWorldRestoreState,
|
||||
runtime_company_annual_creditor_pressure_state, runtime_company_annual_finance_state,
|
||||
runtime_company_assigned_share_pool, runtime_company_average_live_bond_coupon,
|
||||
runtime_company_book_value_per_share, runtime_company_credit_rating,
|
||||
runtime_company_investor_confidence, runtime_company_management_attitude,
|
||||
runtime_company_market_value, runtime_company_prime_rate,
|
||||
runtime_company_annual_creditor_pressure_state, runtime_company_annual_deep_distress_state,
|
||||
runtime_company_annual_finance_state, runtime_company_assigned_share_pool,
|
||||
runtime_company_average_live_bond_coupon, runtime_company_book_value_per_share,
|
||||
runtime_company_credit_rating, 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_stat_value_f64, runtime_company_unassigned_share_pool,
|
||||
runtime_world_annual_finance_mode_active, runtime_world_bankruptcy_allowed,
|
||||
|
|
|
|||
|
|
@ -208,6 +208,25 @@ pub struct RuntimeCompanyAnnualCreditorPressureState {
|
|||
pub eligible_for_bankruptcy_branch: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct RuntimeCompanyAnnualDeepDistressState {
|
||||
pub company_id: u32,
|
||||
#[serde(default)]
|
||||
pub bankruptcy_allowed: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub years_since_founding: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub years_since_last_bankruptcy: Option<u32>,
|
||||
#[serde(default)]
|
||||
pub current_cash: Option<i64>,
|
||||
pub recent_first_three_net_profit_years: Vec<i64>,
|
||||
#[serde(default)]
|
||||
pub deep_distress_cash_floor: Option<i64>,
|
||||
#[serde(default)]
|
||||
pub deep_distress_net_profit_floor: Option<i64>,
|
||||
pub eligible_for_bankruptcy_fallback: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||
pub struct RuntimeTrackPieceCounts {
|
||||
#[serde(default)]
|
||||
|
|
@ -2894,6 +2913,52 @@ pub fn runtime_company_annual_creditor_pressure_state(
|
|||
})
|
||||
}
|
||||
|
||||
pub fn runtime_company_annual_deep_distress_state(
|
||||
state: &RuntimeState,
|
||||
company_id: u32,
|
||||
) -> Option<RuntimeCompanyAnnualDeepDistressState> {
|
||||
let annual_finance_state = runtime_company_annual_finance_state(state, company_id)?;
|
||||
let current_cash = runtime_company_control_transfer_stat_value_f64(
|
||||
state,
|
||||
company_id,
|
||||
RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH,
|
||||
)
|
||||
.and_then(runtime_round_f64_to_i64);
|
||||
let recent_first_three_net_profit_years = annual_finance_state
|
||||
.trailing_full_year_net_profits
|
||||
.iter()
|
||||
.take(3)
|
||||
.copied()
|
||||
.collect::<Vec<_>>();
|
||||
let deep_distress_cash_floor = Some(-300_000);
|
||||
let deep_distress_net_profit_floor = Some(-20_000);
|
||||
let eligible_for_bankruptcy_fallback = runtime_world_bankruptcy_allowed(state) == Some(true)
|
||||
&& current_cash
|
||||
.zip(deep_distress_cash_floor)
|
||||
.is_some_and(|(value, floor)| value <= floor)
|
||||
&& annual_finance_state
|
||||
.years_since_founding
|
||||
.is_some_and(|years| years >= 3)
|
||||
&& recent_first_three_net_profit_years.len() == 3
|
||||
&& recent_first_three_net_profit_years
|
||||
.iter()
|
||||
.all(|value| *value <= deep_distress_net_profit_floor.unwrap())
|
||||
&& annual_finance_state
|
||||
.years_since_last_bankruptcy
|
||||
.is_some_and(|years| years >= 5);
|
||||
Some(RuntimeCompanyAnnualDeepDistressState {
|
||||
company_id,
|
||||
bankruptcy_allowed: runtime_world_bankruptcy_allowed(state),
|
||||
years_since_founding: annual_finance_state.years_since_founding,
|
||||
years_since_last_bankruptcy: annual_finance_state.years_since_last_bankruptcy,
|
||||
current_cash,
|
||||
recent_first_three_net_profit_years,
|
||||
deep_distress_cash_floor,
|
||||
deep_distress_net_profit_floor,
|
||||
eligible_for_bankruptcy_fallback,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn runtime_world_absolute_counter(state: &RuntimeState) -> Option<u32> {
|
||||
state.world_restore.absolute_counter_raw_u32
|
||||
}
|
||||
|
|
@ -6936,6 +7001,118 @@ mod tests {
|
|||
assert!(pressure_state.eligible_for_bankruptcy_branch);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derives_annual_deep_distress_bankruptcy_fallback_from_rehosted_finance_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
|
||||
];
|
||||
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, 0x0d, -350_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 10_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 15_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 3, 12_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -35_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -38_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 3, -33_000.0);
|
||||
|
||||
let state = RuntimeState {
|
||||
calendar: CalendarPoint {
|
||||
year: 1845,
|
||||
month_slot: 0,
|
||||
phase_slot: 0,
|
||||
tick_slot: 0,
|
||||
},
|
||||
world_flags: BTreeMap::new(),
|
||||
save_profile: RuntimeSaveProfileState::default(),
|
||||
world_restore: RuntimeWorldRestoreState {
|
||||
packed_year_word_raw_u16: Some(1845),
|
||||
bankruptcy_policy_raw_u8: Some(0),
|
||||
bankruptcy_allowed: Some(true),
|
||||
..RuntimeWorldRestoreState::default()
|
||||
},
|
||||
metadata: BTreeMap::new(),
|
||||
companies: vec![RuntimeCompany {
|
||||
company_id: 9,
|
||||
current_cash: 0,
|
||||
debt: 0,
|
||||
credit_rating_score: None,
|
||||
prime_rate: None,
|
||||
active: true,
|
||||
available_track_laying_capacity: None,
|
||||
controller_kind: 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([(
|
||||
9,
|
||||
RuntimeCompanyMarketState {
|
||||
founding_year: 1841,
|
||||
last_bankruptcy_year: 1840,
|
||||
year_stat_family_qword_bits,
|
||||
..RuntimeCompanyMarketState::default()
|
||||
},
|
||||
)]),
|
||||
..RuntimeServiceState::default()
|
||||
},
|
||||
};
|
||||
|
||||
let pressure_state =
|
||||
runtime_company_annual_deep_distress_state(&state, 9).expect("deep distress state");
|
||||
assert_eq!(pressure_state.current_cash, Some(-350_000));
|
||||
assert_eq!(
|
||||
pressure_state.recent_first_three_net_profit_years,
|
||||
vec![-25_000, -23_000, -21_000]
|
||||
);
|
||||
assert_eq!(pressure_state.deep_distress_cash_floor, Some(-300_000));
|
||||
assert_eq!(pressure_state.deep_distress_net_profit_floor, Some(-20_000));
|
||||
assert!(pressure_state.eligible_for_bankruptcy_fallback);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_company_market_metrics_from_annual_finance_reader() {
|
||||
let current_issue_calendar_word = 0x0101_0726;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::{
|
||||
CalendarPoint, RuntimeState, runtime_company_annual_creditor_pressure_state,
|
||||
runtime_company_annual_finance_state, runtime_company_unassigned_share_pool,
|
||||
runtime_company_annual_deep_distress_state, runtime_company_annual_finance_state,
|
||||
runtime_company_unassigned_share_pool,
|
||||
};
|
||||
|
||||
fn raw_u32_to_f32_text(raw: u32) -> String {
|
||||
|
|
@ -105,6 +106,11 @@ pub struct RuntimeSummary {
|
|||
pub selected_company_creditor_pressure_current_fuel_cost: Option<i64>,
|
||||
pub selected_company_creditor_pressure_current_fuel_cost_floor: Option<i64>,
|
||||
pub selected_company_creditor_pressure_eligible_for_bankruptcy_branch: Option<bool>,
|
||||
pub selected_company_deep_distress_current_cash: Option<i64>,
|
||||
pub selected_company_deep_distress_recent_first_three_net_profit_years: Vec<i64>,
|
||||
pub selected_company_deep_distress_cash_floor: Option<i64>,
|
||||
pub selected_company_deep_distress_net_profit_floor: Option<i64>,
|
||||
pub selected_company_deep_distress_eligible_for_bankruptcy_fallback: Option<bool>,
|
||||
pub player_count: usize,
|
||||
pub chairman_profile_count: usize,
|
||||
pub active_chairman_profile_count: usize,
|
||||
|
|
@ -198,6 +204,9 @@ impl RuntimeSummary {
|
|||
state.selected_company_id.and_then(|company_id| {
|
||||
runtime_company_annual_creditor_pressure_state(state, company_id)
|
||||
});
|
||||
let selected_company_deep_distress_state = state
|
||||
.selected_company_id
|
||||
.and_then(|company_id| runtime_company_annual_deep_distress_state(state, company_id));
|
||||
Self {
|
||||
calendar: state.calendar,
|
||||
calendar_projection_source: state.metadata.get("save_slice.calendar_source").cloned(),
|
||||
|
|
@ -451,6 +460,26 @@ impl RuntimeSummary {
|
|||
selected_company_creditor_pressure_state
|
||||
.as_ref()
|
||||
.map(|pressure_state| pressure_state.eligible_for_bankruptcy_branch),
|
||||
selected_company_deep_distress_current_cash: selected_company_deep_distress_state
|
||||
.as_ref()
|
||||
.and_then(|pressure_state| pressure_state.current_cash),
|
||||
selected_company_deep_distress_recent_first_three_net_profit_years:
|
||||
selected_company_deep_distress_state
|
||||
.as_ref()
|
||||
.map(|pressure_state| {
|
||||
pressure_state.recent_first_three_net_profit_years.clone()
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
selected_company_deep_distress_cash_floor: selected_company_deep_distress_state
|
||||
.as_ref()
|
||||
.and_then(|pressure_state| pressure_state.deep_distress_cash_floor),
|
||||
selected_company_deep_distress_net_profit_floor: selected_company_deep_distress_state
|
||||
.as_ref()
|
||||
.and_then(|pressure_state| pressure_state.deep_distress_net_profit_floor),
|
||||
selected_company_deep_distress_eligible_for_bankruptcy_fallback:
|
||||
selected_company_deep_distress_state
|
||||
.as_ref()
|
||||
.map(|pressure_state| pressure_state.eligible_for_bankruptcy_fallback),
|
||||
player_count: state.players.len(),
|
||||
chairman_profile_count: state.chairman_profiles.len(),
|
||||
active_chairman_profile_count: state
|
||||
|
|
@ -2436,4 +2465,129 @@ mod tests {
|
|||
Some(true)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn summarizes_selected_company_deep_distress_fallback_state() {
|
||||
let mut year_stat_family_qword_bits = vec![
|
||||
0u64;
|
||||
((crate::RUNTIME_COMPANY_STAT_SLOT_COUNT + 2)
|
||||
* crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
|
||||
as usize
|
||||
];
|
||||
let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
|
||||
let index = (slot_id * crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
|
||||
bits[index] = value.to_bits();
|
||||
};
|
||||
let write_prior_year_value =
|
||||
|bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
|
||||
let index =
|
||||
(slot_id * crate::RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
|
||||
bits[index] = value.to_bits();
|
||||
};
|
||||
write_current_value(&mut year_stat_family_qword_bits, 0x0d, -350_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 10_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 15_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 3, 12_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -35_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -38_000.0);
|
||||
write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 3, -33_000.0);
|
||||
|
||||
let state = RuntimeState {
|
||||
calendar: CalendarPoint {
|
||||
year: 1845,
|
||||
month_slot: 0,
|
||||
phase_slot: 0,
|
||||
tick_slot: 0,
|
||||
},
|
||||
world_flags: BTreeMap::new(),
|
||||
save_profile: RuntimeSaveProfileState::default(),
|
||||
world_restore: RuntimeWorldRestoreState {
|
||||
packed_year_word_raw_u16: Some(1845),
|
||||
bankruptcy_policy_raw_u8: Some(0),
|
||||
bankruptcy_allowed: Some(true),
|
||||
..RuntimeWorldRestoreState::default()
|
||||
},
|
||||
metadata: BTreeMap::new(),
|
||||
companies: vec![RuntimeCompany {
|
||||
company_id: 9,
|
||||
current_cash: 0,
|
||||
debt: 0,
|
||||
credit_rating_score: None,
|
||||
prime_rate: None,
|
||||
active: true,
|
||||
available_track_laying_capacity: None,
|
||||
controller_kind: crate::RuntimeCompanyControllerKind::Unknown,
|
||||
linked_chairman_profile_id: None,
|
||||
book_value_per_share: 0,
|
||||
investor_confidence: 0,
|
||||
management_attitude: 0,
|
||||
takeover_cooldown_year: None,
|
||||
merger_cooldown_year: None,
|
||||
track_piece_counts: RuntimeTrackPieceCounts::default(),
|
||||
}],
|
||||
selected_company_id: Some(9),
|
||||
players: Vec::new(),
|
||||
selected_player_id: None,
|
||||
chairman_profiles: Vec::new(),
|
||||
selected_chairman_profile_id: None,
|
||||
trains: Vec::new(),
|
||||
locomotive_catalog: Vec::new(),
|
||||
cargo_catalog: Vec::new(),
|
||||
territories: Vec::new(),
|
||||
company_territory_track_piece_counts: Vec::new(),
|
||||
company_territory_access: Vec::new(),
|
||||
packed_event_collection: None,
|
||||
event_runtime_records: Vec::new(),
|
||||
candidate_availability: BTreeMap::new(),
|
||||
named_locomotive_availability: BTreeMap::new(),
|
||||
named_locomotive_cost: BTreeMap::new(),
|
||||
all_cargo_price_override: None,
|
||||
named_cargo_price_overrides: BTreeMap::new(),
|
||||
all_cargo_production_override: None,
|
||||
factory_cargo_production_override: None,
|
||||
farm_mine_cargo_production_override: None,
|
||||
named_cargo_production_overrides: BTreeMap::new(),
|
||||
cargo_production_overrides: BTreeMap::new(),
|
||||
world_runtime_variables: BTreeMap::new(),
|
||||
company_runtime_variables: BTreeMap::new(),
|
||||
player_runtime_variables: BTreeMap::new(),
|
||||
territory_runtime_variables: BTreeMap::new(),
|
||||
world_scalar_overrides: BTreeMap::new(),
|
||||
special_conditions: BTreeMap::new(),
|
||||
service_state: RuntimeServiceState {
|
||||
company_market_state: BTreeMap::from([(
|
||||
9,
|
||||
crate::RuntimeCompanyMarketState {
|
||||
founding_year: 1841,
|
||||
last_bankruptcy_year: 1840,
|
||||
year_stat_family_qword_bits,
|
||||
..crate::RuntimeCompanyMarketState::default()
|
||||
},
|
||||
)]),
|
||||
..RuntimeServiceState::default()
|
||||
},
|
||||
};
|
||||
|
||||
let summary = RuntimeSummary::from_state(&state);
|
||||
assert_eq!(
|
||||
summary.selected_company_deep_distress_current_cash,
|
||||
Some(-350_000)
|
||||
);
|
||||
assert_eq!(
|
||||
summary.selected_company_deep_distress_recent_first_three_net_profit_years,
|
||||
vec![-25_000, -23_000, -21_000]
|
||||
);
|
||||
assert_eq!(
|
||||
summary.selected_company_deep_distress_cash_floor,
|
||||
Some(-300_000)
|
||||
);
|
||||
assert_eq!(
|
||||
summary.selected_company_deep_distress_net_profit_floor,
|
||||
Some(-20_000)
|
||||
);
|
||||
assert_eq!(
|
||||
summary.selected_company_deep_distress_eligible_for_bankruptcy_fallback,
|
||||
Some(true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,9 @@ The highest-value next passes are now:
|
|||
the largest live bond principal and the chosen highest-coupon live bond principal into that same
|
||||
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
|
||||
executes as a pure runtime reader over that owner state instead of remaining atlas-only; the
|
||||
later deep-distress bankruptcy fallback now runs on that same save-native cash and trailing-
|
||||
net-profit surface too
|
||||
- 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
|
||||
instead of guessing another derived leaf field from neighboring raw offsets
|
||||
|
|
|
|||
|
|
@ -228,7 +228,9 @@ annual-finance state, so later stock-capital gates can extend a rehosted owner-s
|
|||
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.
|
||||
adjusted share price, and those policy bytes rather than staying in atlas prose only. The later
|
||||
deep-distress bankruptcy fallback now rides the same owner-state seam too, using the save-native
|
||||
cash reader plus the first three trailing net-profit years instead of a parallel raw-offset guess.
|
||||
|
||||
## Why This Boundary
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue