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,221 +0,0 @@
|
||||
use raptor_replica::{
|
||||
content::{ContentPack, Registry},
|
||||
modding::{Command, ScriptRuntime},
|
||||
persistence::Pilot,
|
||||
simulation::{EffectKind, Input, LegacyRng, Outcome, Projectile, World},
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
fn fixture(legacy: bool, automatic: bool) -> (Registry, World, ScriptRuntime) {
|
||||
let pack: ContentPack = serde_json::from_value(json!({
|
||||
"weapons":[{"id":"base:shot","name":"Shot","damage":8,"speed":0,"cooldown":1,"behavior":"straight","target":"all"}],
|
||||
"items":[{"id":"base:forward_guns","name":"Guns","price":0,"weapon":"base:shot","legacy":0},{"id":"base:energy","name":"Shield","price":0,"max_count":100,"legacy":16}],
|
||||
"enemies":[{"id":"base:target","name":"Final Target","health":1,"ground":true,"reward":10}],
|
||||
"missions":[{"id":"base:sector_1_wave_1","name":"Transition Fixture","duration":1,"auto_complete":automatic,"legacy_map":if legacy {Some(123)} else {None}}]
|
||||
})).unwrap();
|
||||
let mut registry = Registry::default();
|
||||
registry.apply(pack, "base").unwrap();
|
||||
let world = World::new(&Pilot::default().mission, &Pilot::default(), ®istry).unwrap();
|
||||
(registry, world, ScriptRuntime::new())
|
||||
}
|
||||
|
||||
fn after_calls(mut rng: LegacyRng, calls: usize) -> i32 {
|
||||
for _ in 0..calls {
|
||||
rng.next_value();
|
||||
}
|
||||
rng.seed
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn original_departure_pauses_at_forty_and_flies_off_before_completion() {
|
||||
let (registry, mut world, mut scripts) = fixture(true, false);
|
||||
world.end_timer = Some(60);
|
||||
for step in 1..=20 {
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert_eq!(world.end_timer, Some(60 - step));
|
||||
assert_eq!(world.outcome, Outcome::Playing);
|
||||
assert!(world.draw_player);
|
||||
assert_eq!((world.player.x, world.player.y), (144, 160));
|
||||
assert_eq!(world.control_paused, step == 20);
|
||||
assert_eq!(world.sounds.contains(&129), step == 20); // FX_FLYBY.
|
||||
}
|
||||
world
|
||||
.step(
|
||||
Input {
|
||||
absolute: Some([280, 0]),
|
||||
fire: true,
|
||||
..Input::default()
|
||||
},
|
||||
®istry,
|
||||
&mut scripts,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!((world.player.x, world.player.y), (152, 156));
|
||||
assert!(world.projectiles.is_empty()); // Paused input cannot fire.
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert_eq!((world.player.x, world.player.y), (160, 148)); // Input+stats movement.
|
||||
while world.outcome == Outcome::Playing {
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
}
|
||||
assert_eq!(world.tick, 61);
|
||||
assert_eq!(world.outcome, Outcome::Complete);
|
||||
assert_eq!((world.player.x, world.player.y), (160, -160));
|
||||
assert!(world.draw_player);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recorded_departure_positions_are_not_moved_a_second_time() {
|
||||
let (registry, mut world, mut scripts) = fixture(true, false);
|
||||
world.end_timer = Some(39);
|
||||
world.control_paused = true;
|
||||
world.departure_delta = [8, -4];
|
||||
world
|
||||
.step(
|
||||
Input {
|
||||
absolute: Some([155, -8]),
|
||||
demo_bank: Some(2),
|
||||
..Input::default()
|
||||
},
|
||||
®istry,
|
||||
&mut scripts,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
(world.player.x, world.player.y, world.player.bank),
|
||||
(155, -8, 2)
|
||||
);
|
||||
assert_eq!(world.end_timer, Some(38));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn final_enemy_removal_arms_immunity_before_hostile_shot_updates() {
|
||||
let (registry, mut world, mut scripts) = fixture(true, true);
|
||||
let entity = world
|
||||
.spawn(&"base:target".into(), 20, 20, ®istry)
|
||||
.unwrap();
|
||||
world
|
||||
.apply_commands(&[Command::Damage { entity, amount: 1 }], ®istry)
|
||||
.unwrap();
|
||||
world.projectiles.push(Projectile {
|
||||
entity: world.next_entity,
|
||||
weapon: "base:shot".into(),
|
||||
x: 160,
|
||||
y: 176,
|
||||
px: 160,
|
||||
py: 176,
|
||||
vx: 0,
|
||||
vy: 0,
|
||||
hostile: true,
|
||||
age: 0,
|
||||
legacy: None,
|
||||
legacy_enemy: None,
|
||||
});
|
||||
world.next_entity += 1;
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert_eq!(world.end_timer, Some(60));
|
||||
assert_eq!(world.player.shield, 100);
|
||||
assert_eq!(world.player.credits, 10);
|
||||
assert_eq!(world.outcome, Outcome::Playing);
|
||||
assert!(world.projectiles.is_empty());
|
||||
let seed = world.rng.seed;
|
||||
world
|
||||
.apply_commands(
|
||||
&[Command::Damage {
|
||||
entity: 0,
|
||||
amount: 500,
|
||||
}],
|
||||
®istry,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(world.player.shield, 100);
|
||||
assert_eq!(world.rng.seed, seed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn original_death_delays_failure_hides_ship_at_twenty_four_and_consumes_full_burst_rng() {
|
||||
let (registry, mut world, mut scripts) = fixture(true, false);
|
||||
world.player.shield = 0;
|
||||
let seed = world.rng;
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert_eq!(world.tick, 1);
|
||||
assert_eq!(world.end_timer, Some(60));
|
||||
assert_eq!(world.outcome, Outcome::Playing);
|
||||
assert!(world.draw_player);
|
||||
assert_eq!(world.rng.seed, after_calls(seed, 4)); // Two x/y positions, no early sound.
|
||||
assert_eq!(world.effects.len(), 2);
|
||||
assert_eq!(world.effects[0].kind, EffectKind::MediumAir);
|
||||
assert_eq!(world.effects[1].kind, EffectKind::SmallAir);
|
||||
let mut positions = seed;
|
||||
let y = 160 + positions.next_value() % 32;
|
||||
let x = 144 + positions.next_value() % 32;
|
||||
assert_eq!((world.effects[0].x, world.effects[0].y), (x, y));
|
||||
let seed = world.rng;
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert_eq!(world.rng.seed, after_calls(seed, 6)); // Two positions, sound pan and pitch.
|
||||
assert!(
|
||||
world
|
||||
.sound_events
|
||||
.iter()
|
||||
.any(|s| s.asset == 104 && matches!(s.pan, 30 | 225))
|
||||
);
|
||||
while world.end_timer != Some(25) {
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert!(world.draw_player);
|
||||
}
|
||||
let seed = world.rng;
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert_eq!(world.end_timer, Some(24));
|
||||
assert!(!world.draw_player);
|
||||
assert_eq!(world.effects.len(), 100); // Original pool cap, despite512requests.
|
||||
assert_eq!(world.rng.seed, after_calls(seed, 1032)); // Palette1,positions4,pitches3,burst1024.
|
||||
assert_eq!(world.sounds.iter().filter(|s| **s == 104).count(), 1);
|
||||
assert_eq!(world.sounds.iter().filter(|s| **s == 109).count(), 2);
|
||||
while world.outcome == Outcome::Playing {
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert!(world.tick <= 62);
|
||||
}
|
||||
assert_eq!(world.tick, 62);
|
||||
assert_eq!(world.outcome, Outcome::Failed);
|
||||
assert!(!world.draw_player);
|
||||
assert!(!world.control_paused);
|
||||
let stopped = world.digest();
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert_eq!(world.digest(), stopped);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authored_mod_missions_keep_their_immediate_outcome_contract() {
|
||||
let (registry, mut world, mut scripts) = fixture(false, true);
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert_eq!(world.outcome, Outcome::Complete);
|
||||
assert_eq!(world.end_timer, None);
|
||||
let (registry, mut world, mut scripts) = fixture(false, false);
|
||||
world.player.shield = 0;
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut scripts)
|
||||
.unwrap();
|
||||
assert_eq!(world.outcome, Outcome::Failed);
|
||||
assert_eq!(world.end_timer, None);
|
||||
}
|
||||
Reference in new issue
Block a user