feat(api): ✨ add hybrid merge query logic
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
426b984b5a
commit
6d6944495e
1 changed files with 72 additions and 0 deletions
|
|
@ -1440,6 +1440,78 @@ impl GdCity {
|
|||
out
|
||||
}
|
||||
|
||||
/// Query which hybrid merges are available for this city given its current
|
||||
/// buildings and the player's researched techs.
|
||||
///
|
||||
/// `registry_json` — JSON array of `BuildingDef` objects (the full game
|
||||
/// pack's building list from DataLoader). Caller passes all buildings; this
|
||||
/// method filters to hybrids.
|
||||
///
|
||||
/// `researched_techs` — list of tech IDs the player has already completed.
|
||||
///
|
||||
/// Returns an `Array` of `Dictionary` values, one per available merge:
|
||||
/// ```text
|
||||
/// {
|
||||
/// "building_a": String, // first prereq id
|
||||
/// "building_b": String, // second prereq id
|
||||
/// "into": String, // hybrid building id
|
||||
/// "tech_gated": bool, // true if military_synthesis not yet researched
|
||||
/// }
|
||||
/// ```
|
||||
/// The returned list includes tech-gated merges so the UI can grey them
|
||||
/// out rather than hide them — the caller decides presentation.
|
||||
#[func]
|
||||
fn available_merges(
|
||||
&self,
|
||||
registry_json: GString,
|
||||
researched_techs: PackedStringArray,
|
||||
) -> Array {
|
||||
use mc_city::{BuildingDef, MERGE_GATING_TECH};
|
||||
|
||||
let defs: Vec<BuildingDef> = match serde_json::from_str(®istry_json.to_string()) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
godot_error!("GdCity::available_merges parse error: {}", e);
|
||||
return Array::new();
|
||||
}
|
||||
};
|
||||
|
||||
// Build fast lookup sets from the city's current buildings.
|
||||
let owned: std::collections::BTreeSet<&str> =
|
||||
self.inner.buildings.iter().map(|s| s.as_str()).collect();
|
||||
|
||||
// Build researched-tech set.
|
||||
let techs: std::collections::BTreeSet<String> = (0..researched_techs.len())
|
||||
.filter_map(|i| researched_techs.get(i).map(|t| t.to_string()))
|
||||
.collect();
|
||||
let tech_gated = !techs.contains(MERGE_GATING_TECH);
|
||||
|
||||
let mut out = Array::new();
|
||||
for def in &defs {
|
||||
// Only hybrid buildings have exactly 2 prereqs.
|
||||
if def.merge_requires.len() != 2 {
|
||||
continue;
|
||||
}
|
||||
let a = def.merge_requires[0].as_str();
|
||||
let b = def.merge_requires[1].as_str();
|
||||
// Both prereqs must be present in the city.
|
||||
if !owned.contains(a) || !owned.contains(b) {
|
||||
continue;
|
||||
}
|
||||
// Irreversibility guard: skip if hybrid already built.
|
||||
if owned.contains(def.id.as_str()) {
|
||||
continue;
|
||||
}
|
||||
let mut entry = Dictionary::new();
|
||||
entry.set("building_a", GString::from(a));
|
||||
entry.set("building_b", GString::from(b));
|
||||
entry.set("into", GString::from(def.id.as_str()));
|
||||
entry.set("tech_gated", tech_gated);
|
||||
out.push(&entry.to_variant());
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Register a building's flat yield bonuses. GDScript passes the
|
||||
/// five per-turn bonuses parsed from the building JSON's `effects` array.
|
||||
/// The city applies these in `get_yields` for each owned building.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue