diff --git a/src/simulator/crates/mc-city/src/city.rs b/src/simulator/crates/mc-city/src/city.rs index 90c4a037..8fb5dad2 100644 --- a/src/simulator/crates/mc-city/src/city.rs +++ b/src/simulator/crates/mc-city/src/city.rs @@ -173,6 +173,11 @@ pub struct City { pub buildings: Vec, #[serde(default)] queues: HashMap, + + /// Per-building flat yield bonuses keyed by building id. + /// Populated by GDScript at game load from JSON `effects` arrays. + #[serde(default)] + building_yields: HashMap, } impl Default for City { @@ -195,6 +200,7 @@ impl Default for City { worked_tiles: Vec::new(), buildings: Vec::new(), queues: HashMap::new(), + building_yields: HashMap::new(), } } } @@ -244,6 +250,7 @@ impl City { worked_tiles: vec![position], buildings: Vec::new(), queues: HashMap::new(), + building_yields: HashMap::new(), } } @@ -264,6 +271,13 @@ impl City { } } + /// Register flat yield bonuses for a building id. Called once per + /// building type at game-data load time; used by `get_yields` to + /// apply effects for any building in `self.buildings`. + pub fn register_building_yields(&mut self, building: impl Into, yields: CityYields) { + self.building_yields.insert(building.into(), yields); + } + // ── Queue accessors (unchanged) ──────────────────────────────── pub fn queue_for(&self, building: &str) -> Option<&BuildingQueue> { @@ -310,6 +324,17 @@ impl City { } } + // Apply building flat bonuses from registered effects + for b in &self.buildings { + if let Some(bonus) = self.building_yields.get(b) { + yields.food += bonus.food; + yields.production += bonus.production; + yields.gold += bonus.gold; + yields.culture += bonus.culture; + yields.science += bonus.science; + } + } + yields } @@ -657,6 +682,16 @@ mod tests { assert_eq!(yields.culture, 2.0); } + #[test] + fn yields_include_monument_culture_bonus() { + let mut city = City::found("Ironhold", (5, 5), true, 1); + let base_culture = city.get_yields(&[]).culture; + city.register_building_yields("monument", CityYields { culture: 2.0, ..Default::default() }); + city.add_building("monument"); + let with_monument = city.get_yields(&[]).culture; + assert!((with_monument - base_culture - 2.0).abs() < 1e-9); + } + #[test] fn yields_sum_worked_tiles() { let mut city = City::found("Ironhold", (5, 5), true, 1);