Decode the EnumUnit tables (schema 35b8dc67) into mission rosters: the distinct combatant `UN_*` ids for one battle, stage props (asteroids, collision meshes) dropped. The tables aren't tagged with their stage on disc, so `stage` is inferred from any `UN_S<NN>_…` prop id in the roster and left None otherwise (honest — ~8 of 31 rosters self-identify). Joined against load_units / load_vessels this gives each battle's combatants with stats, e.g. S01 = ADAN Turret (100 HP), Attacker (500 HP), Destroyer (10000 HP). Example `battle` prints them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
20 lines
1004 B
Rust
20 lines
1004 B
Rust
use sylpheed_formats::{game_data as gd, 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 units=gd::load_units(&pak); let vessels=gd::load_vessels(&pak);
|
|
let hp=|id:&str|->String{
|
|
units.iter().find(|u|u.id.as_deref()==Some(id)).and_then(|u|u.hp).map(|h|format!("{h:.0}hp"))
|
|
.or_else(||vessels.iter().find(|v|v.id.as_deref()==Some(id)).and_then(|v|v.hp).map(|h|format!("{h:.0}HP")))
|
|
.unwrap_or("·".into())
|
|
};
|
|
let rosters=gd::load_unit_rosters(&pak);
|
|
for r in rosters.iter().filter(|r|r.stage.is_some()).take(4){
|
|
println!("\n{} — {} combatants:", r.stage.as_deref().unwrap(), r.units.len());
|
|
for u in r.units.iter().filter(|u|u.contains("ADAN")).take(6){
|
|
let short=u.trim_start_matches("UN_").split('_').skip(1).collect::<Vec<_>>().join("_");
|
|
println!(" {short:32} {}", hp(u));
|
|
}
|
|
}
|
|
}
|