Package RustRaptor and refine controls, menus, saves, sound and mod selection
This commit is contained in:
1 parent
0844f6dffa
commit
e17bc1003e
649 files changed
+8652
-2677
No files matched your search
@@ -1,201 +0,0 @@
|
||||
//! Original-data integration coverage. Run explicitly with --ignored; no game data is tracked.
|
||||
//! The assisted campaign fixture is described in tools/campaign_check.rs.
|
||||
#[path = "../tools/campaign_check.rs"]
|
||||
mod campaign_check;
|
||||
use raptor_replica::{
|
||||
assets::{Catalog, decode_demo},
|
||||
content::ContentId,
|
||||
modding::ScriptRuntime,
|
||||
persistence::Pilot,
|
||||
simulation::{Input, World},
|
||||
};
|
||||
use std::{collections::BTreeSet, path::PathBuf};
|
||||
|
||||
fn catalog_registry() -> (Catalog, raptor_replica::content::Registry) {
|
||||
let root = std::env::var_os("RAPTOR_TEST_DATA")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("data"));
|
||||
campaign_check::catalog_registry(&root).unwrap()
|
||||
}
|
||||
fn registry() -> raptor_replica::content::Registry {
|
||||
catalog_registry().1
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires original untracked catalog; assisted inspection, not ordinary gameplay wins"]
|
||||
fn every_original_wave_reaches_its_end_on_all_four_difficulties() {
|
||||
let registry = registry();
|
||||
assert_eq!(registry.missions.len(), 27);
|
||||
let mut failures = vec![];
|
||||
let mut reports = vec![];
|
||||
for difficulty in 0..=3 {
|
||||
for sector in 1..=3 {
|
||||
for wave in 1..=9 {
|
||||
let report =
|
||||
campaign_check::run_wave(®istry, sector, wave, difficulty, 12000).unwrap();
|
||||
eprintln!("{}", report.csv());
|
||||
if !report.completed()
|
||||
|| report.visited_spawns != report.total_spawns
|
||||
|| report.bosses_seen != report.expected_bosses
|
||||
{
|
||||
failures.push(format!("{report:?}"));
|
||||
}
|
||||
reports.push(report.csv());
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(path) = std::env::var_os("RAPTOR_CAMPAIGN_REPORT") {
|
||||
std::fs::write(
|
||||
path,
|
||||
format!("{}\n{}\n", campaign_check::csv_header(), reports.join("\n")),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
assert!(
|
||||
failures.is_empty(),
|
||||
"Assisted fixture blockers:\n{}",
|
||||
failures.join("\n")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires original untracked catalog; progression fixture bypasses combat"]
|
||||
fn all_original_campaign_and_training_progression_paths_are_available() {
|
||||
let registry = registry();
|
||||
for difficulty in 0..=3 {
|
||||
let mut pilot = Pilot {
|
||||
difficulty,
|
||||
..Pilot::default()
|
||||
};
|
||||
let waves = if difficulty == 0 { 4 } else { 9 };
|
||||
let sectors = if difficulty == 0 { 1 } else { 3 };
|
||||
for sector in 1..=sectors {
|
||||
for wave in 1..=waves {
|
||||
let expected = ContentId::new(format!("base:sector_{sector}_wave_{wave}")).unwrap();
|
||||
assert_eq!(pilot.mission, expected);
|
||||
pilot.complete_mission(®istry).unwrap();
|
||||
pilot.validate(®istry, &[]).unwrap();
|
||||
}
|
||||
}
|
||||
assert_eq!(pilot.mission, ContentId::from("base:sector_1_wave_1"));
|
||||
assert_eq!(pilot.difficulty, (difficulty + 1).min(3));
|
||||
let progress = pilot.legacy_progress.as_ref().unwrap();
|
||||
assert!(progress.waves.iter().all(|wave| *wave == 0));
|
||||
if difficulty == 0 {
|
||||
assert!(progress.training_completed);
|
||||
assert_eq!(pilot.credits, 10000);
|
||||
assert_eq!(pilot.inventory[&"base:energy".into()], 75);
|
||||
} else {
|
||||
assert_eq!(pilot.completed.len(), 27);
|
||||
assert_eq!(&progress.difficulties[..3], &[(difficulty + 1).min(3); 3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires original untracked catalog; assisted weapon exercise, no weapon parity claim"]
|
||||
fn every_original_player_weapon_emits_with_live_mission_targets() {
|
||||
let registry = registry();
|
||||
let weapons: Vec<_> = registry
|
||||
.items
|
||||
.values()
|
||||
.filter(|i| i.weapon.is_some() && i.legacy.is_some())
|
||||
.collect();
|
||||
assert_eq!(weapons.len(), 15);
|
||||
let mut exercised = BTreeSet::new();
|
||||
for item in weapons {
|
||||
let id = item.weapon.clone().unwrap();
|
||||
let mut pilot = Pilot {
|
||||
difficulty: 3,
|
||||
selected: Some(item.id.clone()),
|
||||
..Pilot::default()
|
||||
};
|
||||
pilot.inventory = [
|
||||
(item.id.clone(), item.max_count),
|
||||
("base:energy".into(), 100),
|
||||
]
|
||||
.into_iter()
|
||||
.collect();
|
||||
let mut world = World::new(&pilot.mission, &pilot, ®istry).unwrap();
|
||||
let mut scripts = ScriptRuntime::new();
|
||||
for tick in 0..1500 {
|
||||
world.player.shield = 100;
|
||||
world.player.super_shield = 100;
|
||||
world
|
||||
.step(
|
||||
Input {
|
||||
fire: true,
|
||||
absolute: Some([144, 160]),
|
||||
bomb: tick % 180 == 0,
|
||||
..Input::default()
|
||||
},
|
||||
®istry,
|
||||
&mut scripts,
|
||||
)
|
||||
.unwrap();
|
||||
if world.projectiles.iter().any(|p| p.weapon == id) {
|
||||
exercised.insert(id.clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert!(
|
||||
exercised.contains(&id),
|
||||
"original weapon {id} produced no projectile with mission targets"
|
||||
);
|
||||
}
|
||||
assert_eq!(exercised.len(), 15);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires original catalog and rebuilt C++ full-demo reference trace"]
|
||||
fn complete_demo_1_matches_every_reference_gameplay_snapshot() {
|
||||
let path = std::env::var_os("RAPTOR_REFERENCE_DEMO1")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".reference/cpp-demo1-full.jsonl")
|
||||
});
|
||||
let reference: Vec<serde_json::Value> = std::fs::read_to_string(&path)
|
||||
.expect("produce the trace using the command in docs/campaign-validation.md")
|
||||
.lines()
|
||||
.map(|line| serde_json::from_str(line).unwrap())
|
||||
.collect();
|
||||
assert_eq!(
|
||||
reference.len(),
|
||||
1889,
|
||||
"expected the entire available DEMO1G1 recording"
|
||||
);
|
||||
let (catalog, registry) = catalog_registry();
|
||||
let (sector, wave, frames) = decode_demo(&catalog.named("DEMO1G1_REC").unwrap()).unwrap();
|
||||
assert_eq!(frames.len(), reference.len());
|
||||
let mut pilot = Pilot::demo(sector, ®istry).unwrap();
|
||||
pilot.mission = format!("base:sector_{}_wave_{}", sector + 1, wave + 1)
|
||||
.as_str()
|
||||
.into();
|
||||
let mut world = World::new(&pilot.mission, &pilot, ®istry).unwrap();
|
||||
let mut scripts = ScriptRuntime::new();
|
||||
for (frame, expected) in frames.into_iter().zip(reference) {
|
||||
world
|
||||
.step(
|
||||
Input {
|
||||
fire: frame.buttons[0],
|
||||
cycle: frame.buttons[1],
|
||||
bomb: frame.buttons[2],
|
||||
absolute: Some([frame.x as i32, frame.y as i32]),
|
||||
demo_bank: Some(frame.bank as i32),
|
||||
..Input::default()
|
||||
},
|
||||
®istry,
|
||||
&mut scripts,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
world.reference_state(®istry),
|
||||
expected,
|
||||
"reference mismatch at simulation step {}",
|
||||
world.tick
|
||||
);
|
||||
}
|
||||
assert_eq!(world.tick, 1889);
|
||||
assert_eq!(world.player.shield, 3);
|
||||
assert_eq!(world.player.credits, 60825);
|
||||
}
|
||||
Reference in new issue
Block a user