187 lines
6.0 KiB
Rust
187 lines
6.0 KiB
Rust
use raptor_replica::{
|
|
content::{ContentId, ContentPack, Registry},
|
|
modding::{Command, ScriptRuntime},
|
|
persistence::Pilot,
|
|
simulation::{Input, LineMove, World},
|
|
};
|
|
use serde_json::json;
|
|
|
|
fn fixture() -> Registry {
|
|
let pack: ContentPack = serde_json::from_value(json!({
|
|
"weapons": [{"id":"base:projectile_forward_guns", "name":"Guns", "damage":1,"speed":8,"cooldown":2,"behavior":"straight","target":"all","legacy":0,"art":{"asset":42,"logical_width":4,"logical_height":8,"frames":4}}],
|
|
"items":[
|
|
{"id":"base:forward_guns","name":"Guns","price":0,"weapon":"base:projectile_forward_guns","legacy":0},
|
|
{"id":"base:energy","name":"Shield","price":0,"max_count":100,"legacy":16},
|
|
{"id":"base:super_shield","name":"Super Shield","price":0,"max_count":100,"legacy":15},
|
|
{"id":"base:medkit","name":"Medkit","price":0,"max_count":5,"special":true,"consumable":true,"shield":25,"script":"medkit.rhai"}
|
|
],
|
|
"enemies":[{"id":"base:drone","name":"Drone","speed":1,"health":20,"path":[[0,200]]}],
|
|
"missions":[{"id":"base:sector_1_wave_1","name":"Synthetic Mission","duration":1000}]
|
|
})).unwrap();
|
|
let mut reg = Registry::default();
|
|
reg.apply(pack, "base").unwrap();
|
|
reg.validate().unwrap();
|
|
reg
|
|
}
|
|
|
|
#[test]
|
|
fn original_guns_use_banked_muzzles_and_accelerate_after_position_snapshot() {
|
|
let reg = fixture();
|
|
let mut world = World::new(&"base:sector_1_wave_1".into(), &Pilot::default(), ®).unwrap();
|
|
let mut scripts = ScriptRuntime::new();
|
|
world
|
|
.step(
|
|
Input {
|
|
fire: true,
|
|
demo_bank: Some(3),
|
|
..Input::default()
|
|
},
|
|
®,
|
|
&mut scripts,
|
|
)
|
|
.unwrap();
|
|
// Center (160,176), gun offsets +6/-7, sprite half-size (2,4).
|
|
assert_eq!(
|
|
world
|
|
.projectiles
|
|
.iter()
|
|
.map(|p| (p.x, p.y))
|
|
.collect::<Vec<_>>(),
|
|
[(164, 172), (151, 172)]
|
|
);
|
|
world
|
|
.step(
|
|
Input {
|
|
fire: true,
|
|
..Input::default()
|
|
},
|
|
®,
|
|
&mut scripts,
|
|
)
|
|
.unwrap();
|
|
assert_eq!(world.projectiles.len(), 2);
|
|
assert_eq!(world.projectiles[0].y, 163); // Speed rose from 8 to 9 after the first position.
|
|
world
|
|
.step(
|
|
Input {
|
|
fire: true,
|
|
..Input::default()
|
|
},
|
|
®,
|
|
&mut scripts,
|
|
)
|
|
.unwrap();
|
|
assert_eq!(world.projectiles.len(), 4);
|
|
assert_eq!(world.projectiles[0].y, 153);
|
|
}
|
|
|
|
#[test]
|
|
fn enemy_paths_stop_at_endpoint_but_shots_cross_it() {
|
|
let mut enemy = LineMove::new(0, 0, 2, 1);
|
|
enemy.advance(5);
|
|
assert_eq!((enemy.x, enemy.y), (2, 1));
|
|
let mut shot = LineMove::new(0, 0, 2, 1);
|
|
shot.advance_shot(5);
|
|
assert_eq!((shot.x, shot.y), (5, 3));
|
|
assert!(shot.done);
|
|
}
|
|
|
|
#[test]
|
|
fn mission_transition_preserves_remaining_super_shield() {
|
|
let reg = fixture();
|
|
let mut pilot = Pilot::default();
|
|
pilot.inventory.insert("base:super_shield".into(), 31);
|
|
let mut world = World::new(&pilot.mission, &pilot, ®).unwrap();
|
|
assert_eq!(world.player.super_shield, 31);
|
|
world
|
|
.apply_commands(
|
|
&[Command::Damage {
|
|
entity: 0,
|
|
amount: 12,
|
|
}],
|
|
®,
|
|
)
|
|
.unwrap();
|
|
let saved = world.pilot(&pilot);
|
|
assert_eq!(saved.inventory[&ContentId::from("base:super_shield")], 19);
|
|
assert_eq!(
|
|
World::new(&pilot.mission, &saved, ®)
|
|
.unwrap()
|
|
.player
|
|
.super_shield,
|
|
19
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn moving_an_entity_rebases_its_path() {
|
|
let reg = fixture();
|
|
let mut world = World::new(&"base:sector_1_wave_1".into(), &Pilot::default(), ®).unwrap();
|
|
let entity = world.spawn(&"base:drone".into(), 100, 0, ®).unwrap();
|
|
world
|
|
.apply_commands(
|
|
&[Command::Move {
|
|
entity,
|
|
x: 20,
|
|
y: 20,
|
|
}],
|
|
®,
|
|
)
|
|
.unwrap();
|
|
let mut scripts = ScriptRuntime::new();
|
|
world.step(Input::default(), ®, &mut scripts).unwrap();
|
|
assert_eq!((world.enemies[0].x, world.enemies[0].y), (20, 20));
|
|
world.step(Input::default(), ®, &mut scripts).unwrap();
|
|
assert_eq!((world.enemies[0].x, world.enemies[0].y), (20, 21));
|
|
}
|
|
|
|
#[test]
|
|
fn consumable_use_has_snapshot_and_only_fires_on_press() {
|
|
let reg = fixture();
|
|
let mut pilot = Pilot::default();
|
|
pilot.inventory.insert("base:medkit".into(), 2);
|
|
pilot.inventory.insert("base:energy".into(), 50);
|
|
pilot.selected = Some("base:medkit".into());
|
|
let mut world = World::new(&pilot.mission, &pilot, ®).unwrap();
|
|
let mut scripts = ScriptRuntime::new();
|
|
scripts.add("base","medkit.rhai",r#"fn on_use(event,state,rng) {#{commands:[#{op:"credits",amount:7}], state:#{shield:event.player.shield,quantity:event.player.inventory["base:medkit"]}}}"#).unwrap();
|
|
world
|
|
.step(
|
|
Input {
|
|
special: true,
|
|
..Input::default()
|
|
},
|
|
®,
|
|
&mut scripts,
|
|
)
|
|
.unwrap();
|
|
assert_eq!(world.player.shield, 75);
|
|
assert_eq!(world.player.credits, 7);
|
|
assert_eq!(world.player.inventory[&ContentId::from("base:medkit")], 1);
|
|
world
|
|
.step(
|
|
Input {
|
|
special: true,
|
|
..Input::default()
|
|
},
|
|
®,
|
|
&mut scripts,
|
|
)
|
|
.unwrap();
|
|
assert_eq!(world.player.credits, 7);
|
|
world.step(Input::default(), ®, &mut scripts).unwrap();
|
|
world
|
|
.step(
|
|
Input {
|
|
special: true,
|
|
..Input::default()
|
|
},
|
|
®,
|
|
&mut scripts,
|
|
)
|
|
.unwrap();
|
|
assert_eq!(world.player.shield, 100);
|
|
assert_eq!(world.player.credits, 14);
|
|
assert_eq!(world.player.selected, None);
|
|
}
|