Add company market reader seam
This commit is contained in:
parent
a73a789bac
commit
53f1078a84
5 changed files with 212 additions and 9 deletions
|
|
@ -68,7 +68,10 @@ state too, deriving assigned shares, public float, and rounded cached share pric
|
||||||
company market reader instead of scattering more finance helpers across the runtime. A checked-in
|
company market reader instead of scattering more finance helpers across the runtime. A checked-in
|
||||||
The fixed-world finance neighborhood itself is now widened to 16 dwords rooted at `[world+0x11]`,
|
The fixed-world finance neighborhood itself is now widened to 16 dwords rooted at `[world+0x11]`,
|
||||||
so future issue-`0x38/0x39` closure can build on a broader owned restore-state window rather than
|
so future issue-`0x38/0x39` closure can build on a broader owned restore-state window rather than
|
||||||
another narrow one-off probe. A checked-in
|
another narrow one-off probe. The next company-side seam is now bundled too: a shared company
|
||||||
|
market reader now exposes outstanding shares, assigned shares, public float, rounded cached share
|
||||||
|
price, salary lanes, bonus amount, and issue-calendar words from the owned annual-finance state
|
||||||
|
instead of leaving that logic spread across summary helpers. A checked-in
|
||||||
The working rule on the remaining frontier is explicit now too: when a lane is still ambiguous, we
|
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
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,12 @@ pub use runtime::{
|
||||||
RuntimeCargoCatalogEntry, RuntimeCargoClass, RuntimeCargoPriceTarget,
|
RuntimeCargoCatalogEntry, RuntimeCargoClass, RuntimeCargoPriceTarget,
|
||||||
RuntimeCargoProductionTarget, RuntimeChairmanMetric, RuntimeChairmanProfile,
|
RuntimeCargoProductionTarget, RuntimeChairmanMetric, RuntimeChairmanProfile,
|
||||||
RuntimeChairmanTarget, RuntimeCompany, RuntimeCompanyAnnualFinanceState,
|
RuntimeChairmanTarget, RuntimeCompany, RuntimeCompanyAnnualFinanceState,
|
||||||
RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind, RuntimeCompanyMarketState,
|
RuntimeCompanyConditionTestScope, RuntimeCompanyControllerKind, RuntimeCompanyMarketMetric,
|
||||||
RuntimeCompanyMetric, RuntimeCompanyStatBandCandidate, RuntimeCompanyStatSelector,
|
RuntimeCompanyMarketState, RuntimeCompanyMetric, RuntimeCompanyStatBandCandidate,
|
||||||
RuntimeCompanyTarget, RuntimeCompanyTerritoryAccess, RuntimeCompanyTerritoryTrackPieceCount,
|
RuntimeCompanyStatSelector, RuntimeCompanyTarget, RuntimeCompanyTerritoryAccess,
|
||||||
RuntimeCondition, RuntimeConditionComparator, RuntimeEffect, RuntimeEventRecord,
|
RuntimeCompanyTerritoryTrackPieceCount, RuntimeCondition, RuntimeConditionComparator,
|
||||||
RuntimeEventRecordTemplate, RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary,
|
RuntimeEffect, RuntimeEventRecord, RuntimeEventRecordTemplate,
|
||||||
|
RuntimeLocomotiveCatalogEntry, RuntimePackedEventCollectionSummary,
|
||||||
RuntimePackedEventCompactControlSummary, RuntimePackedEventConditionRowSummary,
|
RuntimePackedEventCompactControlSummary, RuntimePackedEventConditionRowSummary,
|
||||||
RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventNegativeSentinelScopeSummary,
|
RuntimePackedEventGroupedEffectRowSummary, RuntimePackedEventNegativeSentinelScopeSummary,
|
||||||
RuntimePackedEventRecordSummary, RuntimePackedEventTextBandSummary, RuntimePlayer,
|
RuntimePackedEventRecordSummary, RuntimePackedEventTextBandSummary, RuntimePlayer,
|
||||||
|
|
@ -62,7 +63,8 @@ pub use runtime::{
|
||||||
RUNTIME_COMPANY_STAT_FAMILY_CONTROL_TRANSFER, RUNTIME_COMPANY_STAT_SLOT_BOOK_VALUE_PER_SHARE,
|
RUNTIME_COMPANY_STAT_FAMILY_CONTROL_TRANSFER, RUNTIME_COMPANY_STAT_SLOT_BOOK_VALUE_PER_SHARE,
|
||||||
RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH, RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE,
|
RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH, RUNTIME_WORLD_ISSUE_INVESTOR_CONFIDENCE,
|
||||||
runtime_company_annual_finance_state, runtime_company_assigned_share_pool,
|
runtime_company_annual_finance_state, runtime_company_assigned_share_pool,
|
||||||
runtime_company_stat_value, runtime_company_unassigned_share_pool, runtime_world_issue_state,
|
runtime_company_market_value, runtime_company_stat_value,
|
||||||
|
runtime_company_unassigned_share_pool, runtime_world_issue_state,
|
||||||
};
|
};
|
||||||
pub use smp::{
|
pub use smp::{
|
||||||
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,
|
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,
|
||||||
|
|
|
||||||
|
|
@ -342,6 +342,20 @@ pub enum RuntimeCompanyMetric {
|
||||||
TrackPiecesNonElectric,
|
TrackPiecesNonElectric,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum RuntimeCompanyMarketMetric {
|
||||||
|
OutstandingShares,
|
||||||
|
AssignedSharePool,
|
||||||
|
UnassignedSharePool,
|
||||||
|
CachedSharePrice,
|
||||||
|
ChairmanSalaryBaseline,
|
||||||
|
ChairmanSalaryCurrent,
|
||||||
|
ChairmanBonusAmount,
|
||||||
|
CurrentIssueCalendarWord,
|
||||||
|
PriorIssueCalendarWord,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum RuntimeChairmanMetric {
|
pub enum RuntimeChairmanMetric {
|
||||||
|
|
@ -1910,6 +1924,41 @@ pub fn runtime_company_annual_finance_state(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn runtime_company_market_value(
|
||||||
|
state: &RuntimeState,
|
||||||
|
company_id: u32,
|
||||||
|
metric: RuntimeCompanyMarketMetric,
|
||||||
|
) -> Option<i64> {
|
||||||
|
let annual_finance_state = runtime_company_annual_finance_state(state, company_id)?;
|
||||||
|
match metric {
|
||||||
|
RuntimeCompanyMarketMetric::OutstandingShares => {
|
||||||
|
Some(annual_finance_state.outstanding_shares as i64)
|
||||||
|
}
|
||||||
|
RuntimeCompanyMarketMetric::AssignedSharePool => {
|
||||||
|
Some(annual_finance_state.assigned_share_pool as i64)
|
||||||
|
}
|
||||||
|
RuntimeCompanyMarketMetric::UnassignedSharePool => {
|
||||||
|
Some(annual_finance_state.unassigned_share_pool as i64)
|
||||||
|
}
|
||||||
|
RuntimeCompanyMarketMetric::CachedSharePrice => annual_finance_state.cached_share_price,
|
||||||
|
RuntimeCompanyMarketMetric::ChairmanSalaryBaseline => {
|
||||||
|
Some(annual_finance_state.chairman_salary_baseline as i64)
|
||||||
|
}
|
||||||
|
RuntimeCompanyMarketMetric::ChairmanSalaryCurrent => {
|
||||||
|
Some(annual_finance_state.chairman_salary_current as i64)
|
||||||
|
}
|
||||||
|
RuntimeCompanyMarketMetric::ChairmanBonusAmount => {
|
||||||
|
Some(annual_finance_state.chairman_bonus_amount as i64)
|
||||||
|
}
|
||||||
|
RuntimeCompanyMarketMetric::CurrentIssueCalendarWord => {
|
||||||
|
Some(annual_finance_state.current_issue_calendar_word as i64)
|
||||||
|
}
|
||||||
|
RuntimeCompanyMarketMetric::PriorIssueCalendarWord => {
|
||||||
|
Some(annual_finance_state.prior_issue_calendar_word as i64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn rounded_cached_share_price_i64(raw_u32: u32) -> Option<i64> {
|
fn rounded_cached_share_price_i64(raw_u32: u32) -> Option<i64> {
|
||||||
let value = f32::from_bits(raw_u32);
|
let value = f32::from_bits(raw_u32);
|
||||||
if !value.is_finite() {
|
if !value.is_finite() {
|
||||||
|
|
@ -4191,4 +4240,149 @@ mod tests {
|
||||||
assert_eq!(runtime_company_assigned_share_pool(&state, 99), None);
|
assert_eq!(runtime_company_assigned_share_pool(&state, 99), None);
|
||||||
assert_eq!(runtime_company_annual_finance_state(&state, 99), None);
|
assert_eq!(runtime_company_annual_finance_state(&state, 99), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reads_company_market_metrics_from_annual_finance_reader() {
|
||||||
|
let state = RuntimeState {
|
||||||
|
calendar: CalendarPoint {
|
||||||
|
year: 1830,
|
||||||
|
month_slot: 0,
|
||||||
|
phase_slot: 0,
|
||||||
|
tick_slot: 0,
|
||||||
|
},
|
||||||
|
world_flags: BTreeMap::new(),
|
||||||
|
save_profile: RuntimeSaveProfileState::default(),
|
||||||
|
world_restore: RuntimeWorldRestoreState::default(),
|
||||||
|
metadata: BTreeMap::new(),
|
||||||
|
companies: vec![RuntimeCompany {
|
||||||
|
company_id: 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![RuntimeChairmanProfile {
|
||||||
|
profile_id: 1,
|
||||||
|
name: "Chairman One".to_string(),
|
||||||
|
active: true,
|
||||||
|
current_cash: 0,
|
||||||
|
linked_company_id: Some(7),
|
||||||
|
company_holdings: BTreeMap::from([(7, 12_000)]),
|
||||||
|
holdings_value_total: 0,
|
||||||
|
net_worth_total: 0,
|
||||||
|
purchasing_power_total: 0,
|
||||||
|
}],
|
||||||
|
selected_chairman_profile_id: None,
|
||||||
|
trains: Vec::new(),
|
||||||
|
locomotive_catalog: Vec::new(),
|
||||||
|
cargo_catalog: Vec::new(),
|
||||||
|
territories: Vec::new(),
|
||||||
|
company_territory_track_piece_counts: Vec::new(),
|
||||||
|
company_territory_access: Vec::new(),
|
||||||
|
packed_event_collection: None,
|
||||||
|
event_runtime_records: Vec::new(),
|
||||||
|
candidate_availability: BTreeMap::new(),
|
||||||
|
named_locomotive_availability: BTreeMap::new(),
|
||||||
|
named_locomotive_cost: BTreeMap::new(),
|
||||||
|
all_cargo_price_override: None,
|
||||||
|
named_cargo_price_overrides: BTreeMap::new(),
|
||||||
|
all_cargo_production_override: None,
|
||||||
|
factory_cargo_production_override: None,
|
||||||
|
farm_mine_cargo_production_override: None,
|
||||||
|
named_cargo_production_overrides: BTreeMap::new(),
|
||||||
|
cargo_production_overrides: BTreeMap::new(),
|
||||||
|
world_runtime_variables: BTreeMap::new(),
|
||||||
|
company_runtime_variables: BTreeMap::new(),
|
||||||
|
player_runtime_variables: BTreeMap::new(),
|
||||||
|
territory_runtime_variables: BTreeMap::new(),
|
||||||
|
world_scalar_overrides: BTreeMap::new(),
|
||||||
|
special_conditions: BTreeMap::new(),
|
||||||
|
service_state: RuntimeServiceState {
|
||||||
|
company_market_state: BTreeMap::from([(
|
||||||
|
7,
|
||||||
|
RuntimeCompanyMarketState {
|
||||||
|
outstanding_shares: 20_000,
|
||||||
|
cached_share_price_raw_u32: 0x42200000,
|
||||||
|
chairman_salary_baseline: 18,
|
||||||
|
chairman_salary_current: 27,
|
||||||
|
chairman_bonus_year: 1843,
|
||||||
|
chairman_bonus_amount: 625,
|
||||||
|
founding_year: 1832,
|
||||||
|
last_bankruptcy_year: 0,
|
||||||
|
last_dividend_year: 1842,
|
||||||
|
current_issue_calendar_word: 9,
|
||||||
|
prior_issue_calendar_word: 8,
|
||||||
|
..RuntimeCompanyMarketState::default()
|
||||||
|
},
|
||||||
|
)]),
|
||||||
|
..RuntimeServiceState::default()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
runtime_company_market_value(&state, 7, RuntimeCompanyMarketMetric::OutstandingShares),
|
||||||
|
Some(20_000)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
runtime_company_market_value(&state, 7, RuntimeCompanyMarketMetric::AssignedSharePool),
|
||||||
|
Some(12_000)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
runtime_company_market_value(&state, 7, RuntimeCompanyMarketMetric::UnassignedSharePool),
|
||||||
|
Some(8_000)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
runtime_company_market_value(&state, 7, RuntimeCompanyMarketMetric::CachedSharePrice),
|
||||||
|
Some(40)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
runtime_company_market_value(
|
||||||
|
&state,
|
||||||
|
7,
|
||||||
|
RuntimeCompanyMarketMetric::CurrentIssueCalendarWord
|
||||||
|
),
|
||||||
|
Some(9)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
runtime_company_market_value(
|
||||||
|
&state,
|
||||||
|
7,
|
||||||
|
RuntimeCompanyMarketMetric::PriorIssueCalendarWord
|
||||||
|
),
|
||||||
|
Some(8)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
runtime_company_market_value(
|
||||||
|
&state,
|
||||||
|
7,
|
||||||
|
RuntimeCompanyMarketMetric::ChairmanSalaryCurrent
|
||||||
|
),
|
||||||
|
Some(27)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
runtime_company_market_value(
|
||||||
|
&state,
|
||||||
|
7,
|
||||||
|
RuntimeCompanyMarketMetric::ChairmanBonusAmount
|
||||||
|
),
|
||||||
|
Some(625)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
runtime_company_market_value(&state, 99, RuntimeCompanyMarketMetric::OutstandingShares),
|
||||||
|
None
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,8 @@ The highest-value next passes are now:
|
||||||
finance logic; that same owned company market state now also backs a bundled annual-finance
|
finance logic; that same owned company market state now also backs a bundled annual-finance
|
||||||
reader seam for assigned shares, public float, and rounded cached share price; the fixed-world
|
reader seam for assigned shares, public float, and rounded cached share price; the fixed-world
|
||||||
finance neighborhood is now widened to 16 dwords rooted at `[world+0x11]` so later issue-family
|
finance neighborhood is now widened to 16 dwords rooted at `[world+0x11]` so later issue-family
|
||||||
closure can target a broader owned restore-state window
|
closure can target a broader owned restore-state window; the same annual-finance state now also
|
||||||
|
feeds a shared company market reader for stock-capital, salary, bonus, and issue-calendar values
|
||||||
- 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
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,10 @@ supports a bundled annual-finance reader seam for assigned shares, public float,
|
||||||
cached share price, which is a better base for later dividend / issue-calendar simulation than
|
cached share price, which is a better base for later dividend / issue-calendar simulation than
|
||||||
scattered single-field helpers. The fixed-world finance neighborhood is now widened to 16 dwords
|
scattered single-field helpers. The fixed-world finance neighborhood is now widened to 16 dwords
|
||||||
rooted at `[world+0x11]`, so later issue-`0x38/0x39` closure can build on a broader owned
|
rooted at `[world+0x11]`, so later issue-`0x38/0x39` closure can build on a broader owned
|
||||||
restore-state window instead of another narrow probe.
|
restore-state window instead of another narrow probe. The same owned company annual-finance state
|
||||||
|
now also drives a shared company market reader seam for stock-capital, salary, bonus, and
|
||||||
|
issue-calendar values, which is a better base for shellless finance simulation than summary-only
|
||||||
|
helpers.
|
||||||
|
|
||||||
## Why This Boundary
|
## Why This Boundary
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue