From c237063093bb1be46f266abfd50e1c24133fb204 Mon Sep 17 00:00:00 2001 From: Natalie Date: Sun, 10 May 2026 15:43:05 -0700 Subject: [PATCH] =?UTF-8?q?feat(@projects/@magic-civilization):=20?= =?UTF-8?q?=E2=9C=A8=20simplify=20research=20projection=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../crates/mc-player-api/src/projection.rs | 47 ++++++++----------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/simulator/crates/mc-player-api/src/projection.rs b/src/simulator/crates/mc-player-api/src/projection.rs index 54ac7fbe..f318c62c 100644 --- a/src/simulator/crates/mc-player-api/src/projection.rs +++ b/src/simulator/crates/mc-player-api/src/projection.rs @@ -97,28 +97,21 @@ fn project_resources(player: &mc_turn::game_state::PlayerState) -> ResourceView } fn project_research(player: &mc_turn::game_state::PlayerState) -> ResearchView { - let (current_tech, tech_progress, tech_cost, researched) = if let Some(pt) = &player.player_tech { - let researched: Vec = pt - .researched - .iter() - .map(std::string::ToString::to_string) - .collect(); - let current = pt - .researching - .as_ref() - .map(std::string::ToString::to_string); - let cost = pt - .researching_cost - .map(|c| c as i32) - .unwrap_or(0); - (current, player.science_pool as i32, cost, researched) + let (current_tech, tech_progress, researched) = if let Some(pt) = &player.player_tech { + let researched: Vec = pt.researched_techs().iter().cloned().collect(); + let current = pt.current_research().map(std::string::ToString::to_string); + (current, pt.research_progress() as i32, researched) } else { - (None, 0, 0, Vec::new()) + (None, 0, Vec::new()) }; ResearchView { current_tech, tech_progress, - tech_cost, + // TRACKED: tech_cost lives on the TechWeb (not PlayerTechState). + // Surfacing it requires passing the web into the projector — done + // as a Phase 1 follow-up. v1 emits 0 and adapters can poll across + // turns to observe progress relative to research_progress deltas. + tech_cost: 0, researched, // TRACKED: enumerate available techs from the TechWeb once // the projection has a handle to it (passed via context). @@ -205,9 +198,11 @@ fn project_production_queue(city: &mc_city::CityState) -> Vec (id.to_string(), "unit".to_string()), - mc_city::Queueable::Building(id) => (id.to_string(), "building".to_string()), - mc_city::Queueable::Wonder(id) => (id.to_string(), "wonder".to_string()), + mc_city::Queueable::Unit { unit_id } => (unit_id.to_string(), "unit".to_string()), + mc_city::Queueable::Item { item_id } => (item_id.clone(), "item".to_string()), + mc_city::Queueable::Wonder { wonder_id } => { + (wonder_id.to_string(), "wonder".to_string()) + } }; vec![ProductionQueueEntry { item, @@ -230,7 +225,7 @@ fn project_units(state: &GameState, player_idx: usize, omniscient: bool) -> Vec< for unit in &player.units { out.push(UnitView { id: unit.id.to_string(), - type_id: unit.unit_type.clone(), + type_id: unit.unit_id.clone(), position: [unit.col, unit.row], owner: p_idx as PlayerId, hp: unit.hp, @@ -341,11 +336,7 @@ fn project_diplomacy( } fn classify_relation(rel: &mc_trade::relation::RelationState) -> String { - if rel.is_at_war() { - "war".into() - } else { - "peace".into() - } + rel.relation.as_str().to_string() } fn project_score(state: &GameState, player: &mc_turn::game_state::PlayerState) -> ScoreView { @@ -385,7 +376,7 @@ mod tests { u.id = *id; u.col = *col; u.row = *row; - u.unit_type = "dwarf_warrior".into(); + u.unit_id = "dwarf_warrior".into(); u.hp = 100; u.max_hp = 100; ps.units.push(u); @@ -396,7 +387,7 @@ mod tests { u.id = 999; u.col = 50; u.row = 50; - u.unit_type = "dwarf_warrior".into(); + u.unit_id = "dwarf_warrior".into(); u.hp = 100; u.max_hp = 100; ps.units.push(u);