feat(mc-city): Introduce yield bonus registration logic with Rust structs for yield types and GDScript integration for simulator yield handling

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
autocommit 2026-04-15 23:45:33 -07:00
parent a7695432f9
commit c6d22a99a0

View file

@ -173,6 +173,11 @@ pub struct City {
pub buildings: Vec<String>,
#[serde(default)]
queues: HashMap<String, BuildingQueue>,
/// Per-building flat yield bonuses keyed by building id.
/// Populated by GDScript at game load from JSON `effects` arrays.
#[serde(default)]
building_yields: HashMap<String, CityYields>,
}
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<String>, 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);