use sylpheed_formats::{idxd::IdxdObject, PakArchive}; fn short(s: &str) -> String { s.trim_start_matches("Weapon_") .trim_start_matches("UN_") .trim_start_matches("UnitName_UN_") .into() } fn g<'a>(o: &'a IdxdObject, k: &str) -> String { o.get_f32(k) .map(|v| { if v == v.trunc() { format!("{}", v as i64) } else { format!("{v}") } }) .or_else(|| { o.get_raw(k) .filter(|x| { x.chars() .next() .map(|c| c.is_ascii_digit()) .unwrap_or(false) }) .map(|s| s.to_string()) }) .unwrap_or("·".into()) } fn main() { let disc = std::env::var("SYLPHEED_DISC").unwrap(); let arc = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).unwrap(); let recs = |want: u32| -> Vec { arc.entries() .iter() .filter_map(|e| arc.read(e).ok()) .filter_map(|b| IdxdObject::parse(&b).ok()) .filter(|o| o.schema_hash == want) .collect() }; println!("### WEAPONS (name | target | load | int | power | vel | range | trig)"); for o in recs(0x6ab4825a).iter().take(16) { println!( "{:<34}\t{}\t{}\t{}\t{}\t{}\t{}\t{}", short(o.get_raw("ID").unwrap_or("?")), o.get_raw("TargetType").unwrap_or("·"), g(o, "LoadingCount"), g(o, "Interval"), g(o, "Power"), g(o, "Velocity"), g(o, "MaximumRange"), g(o, "TriggerShotCount") ); } println!("\n### UNITS/CRAFT (name | HP | cruise | accel | radar | turrets | score)"); for o in recs(0x43faa517).iter().take(16) { println!( "{:<38}\t{}\t{}\t{}\t{}\t{}\t{}", short(o.get_raw("ID").unwrap_or("?")), g(o, "HP"), g(o, "CruisingVelocity"), g(o, "Acceleration"), g(o, "RadarRange"), g(o, "TurretCount"), g(o, "ScorePoint") ); } println!("\n### VESSELS/CAPITAL SHIPS (name | HP | Sz_X | Sz_Z | radar | turrets | bridges | hatches | shieldgen | thrusters)"); for o in recs(0x3c5b0549).iter() { println!( "{:<30}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}", short(o.get_raw("ID").unwrap_or("?")), g(o, "HP"), g(o, "Size_X"), g(o, "Size_Z"), g(o, "RadarRange"), g(o, "TurretCount"), g(o, "BridgeCount"), g(o, "HatchCount"), g(o, "ShieldGeneratorCount"), g(o, "ThrusterCount") ); } }