use sylpheed_formats::{game_data, localization::TextIndex, PakArchive}; fn main() { let disc = std::env::var("SYLPHEED_DISC").unwrap(); let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).unwrap(); let text = TextIndex::build(&pak); let mut stages = game_data::load_stages(&pak); stages.retain(|s| { s.id.starts_with('S') && s.id.len() == 3 && s.id[1..].parse::().map(|n| n <= 16).unwrap_or(false) }); stages.sort_by(|a, b| a.id.cmp(&b.id)); println!("═══ CAMPAIGN (S01–S16) ═══"); for s in &stages { let obj = text.objectives(&s.id, 1); println!("\n{} · {}", s.id, s.location.as_deref().unwrap_or("?")); for o in obj.iter().take(2) { println!(" ▸ {o}"); } } // roster with real names let mut chars = game_data::load_characters(&pak); chars.retain(|c| { c.faction.as_deref() == Some("TCAF") && c.unique == Some(true) && c.faces.len() >= 4 }); println!("\n═══ PRINCIPAL CAST (TCAF, named) ═══"); for c in &chars { let id = c.id.as_deref().unwrap_or(""); let name = text .character_name(id.trim_start_matches("Character")) .or_else(|| c.name_key.as_deref().and_then(|k| text.get(k))) .unwrap_or("?"); println!( " {name:12} ({} portraits) [{}]", c.faces.len(), id.trim_start_matches("Character") ); } }