feat(@projects/@magic-civilization): simplify research projection logic

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-05-10 15:43:05 -07:00
parent 950323ef97
commit c237063093

View file

@ -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<String> = 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<String> = 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<ProductionQueueEnt
return Vec::new();
};
let (item, kind) = match q {
mc_city::Queueable::Unit(id) => (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);