Make RustRaptor the repository root and track its playable bundle
This commit is contained in:
1 parent
4b1edefeec
commit
8f459796b1
9860 files changed
+21084
-61019
No files matched your search
@@ -0,0 +1,263 @@
|
||||
//! A confirmed changed-capacity save retains equipment without increasing the
|
||||
//! original combat shield limits or losing quantities on additive operations.
|
||||
use raptor_replica::{
|
||||
content::{ContentId, ContentPack, Registry},
|
||||
modding::{Command, ScriptRuntime},
|
||||
persistence::Pilot,
|
||||
simulation::{Input, Pickup, World},
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
fn registry() -> Registry {
|
||||
let mut registry = Registry::default();
|
||||
let pack: ContentPack = serde_json::from_value(json!({
|
||||
"items": [
|
||||
{"id":"base:forward_guns","name":"Guns","price":0},
|
||||
{"id":"base:energy","name":"Energy","price":0,"max_count":100,"initial_count":25,"shield":25,"legacy":16},
|
||||
{"id":"base:super_shield","name":"Super Shield","price":0,"max_count":100,"initial_count":100,"legacy":15},
|
||||
{"id":"base:ammo","name":"Ammo","price":0,"max_count":3}
|
||||
],
|
||||
"missions":[{"id":"base:sector_1_wave_1","name":"Test","duration":10000}]
|
||||
})).unwrap();
|
||||
registry.apply(pack, "base").unwrap();
|
||||
registry.validate().unwrap();
|
||||
registry
|
||||
}
|
||||
fn id(value: &str) -> ContentId {
|
||||
value.into()
|
||||
}
|
||||
fn overflowing() -> Pilot {
|
||||
let mut pilot = Pilot::default();
|
||||
pilot.inventory.insert(id("base:energy"), 105);
|
||||
pilot.inventory.insert(id("base:super_shield"), 125);
|
||||
pilot.super_shield_reserves = vec![130];
|
||||
pilot
|
||||
}
|
||||
fn command(world: &mut World, registry: &Registry, command: Command) {
|
||||
world.apply_commands(&[command], registry).unwrap();
|
||||
}
|
||||
fn collect(world: &mut World, registry: &Registry, item: &str) {
|
||||
world.pickups.push(Pickup {
|
||||
entity: 123,
|
||||
item: item.into(),
|
||||
x: world.player.x,
|
||||
y: world.player.y,
|
||||
legacy: None,
|
||||
});
|
||||
world
|
||||
.step(Input::default(), registry, &mut ScriptRuntime::new())
|
||||
.unwrap();
|
||||
assert!(world.pickups.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn confirmed_load_steps_and_snapshots_keep_full_charge_with_bounded_usable_shields() {
|
||||
let registry = registry();
|
||||
let saved = overflowing();
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let path = dir.path().join("pilot.json");
|
||||
saved.save(&path).unwrap();
|
||||
let loaded = Pilot::inspect_load(&path, ®istry, &[]).unwrap();
|
||||
assert!(!loaded.compatibility.is_compatible());
|
||||
let pilot = loaded.confirm_load();
|
||||
let mut world = World::new(&pilot.mission, &pilot, ®istry).unwrap();
|
||||
assert_eq!((world.player.shield, world.player.super_shield), (100, 100));
|
||||
for _ in 0..10 {
|
||||
world
|
||||
.step(Input::default(), ®istry, &mut ScriptRuntime::new())
|
||||
.unwrap();
|
||||
}
|
||||
let after = world.pilot(&pilot);
|
||||
assert_eq!(after.inventory, saved.inventory);
|
||||
assert_eq!(after.super_shield_reserves, saved.super_shield_reserves);
|
||||
// A serialized in-progress world also keeps its retained charge.
|
||||
let world: World = serde_json::from_value(serde_json::to_value(world).unwrap()).unwrap();
|
||||
assert_eq!(world.pilot(&pilot).inventory, saved.inventory);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn original_world_serialization_omits_overflow_and_old_worlds_default_to_zero() {
|
||||
let registry = registry();
|
||||
let pilot = Pilot::default();
|
||||
let world = World::new(&pilot.mission, &pilot, ®istry).unwrap();
|
||||
let value = serde_json::to_value(world).unwrap();
|
||||
assert!(value.get("energy_overflow").is_none());
|
||||
assert!(value.get("super_shield_overflow").is_none());
|
||||
let decoded: World = serde_json::from_value(value).unwrap();
|
||||
assert_eq!(
|
||||
(decoded.energy_overflow, decoded.super_shield_overflow),
|
||||
(0, 0)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn damage_consumes_usable_charge_and_destroyed_modules_do_not_resurrect_overflow() {
|
||||
let registry = registry();
|
||||
let pilot = overflowing();
|
||||
let mut world = World::new(&pilot.mission, &pilot, ®istry).unwrap();
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::Damage {
|
||||
entity: 0,
|
||||
amount: 20,
|
||||
},
|
||||
);
|
||||
assert_eq!(world.player.super_shield, 80);
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:super_shield")], 105);
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::Damage {
|
||||
entity: 0,
|
||||
amount: 81,
|
||||
},
|
||||
);
|
||||
assert_eq!(world.player.super_shield, 100);
|
||||
assert_eq!(world.super_shield_overflow, 30);
|
||||
assert!(world.player.super_shield_reserves.is_empty());
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:super_shield")], 130);
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::Damage {
|
||||
entity: 0,
|
||||
amount: 101,
|
||||
},
|
||||
);
|
||||
assert_eq!(world.super_shield_overflow, 0);
|
||||
assert!(
|
||||
!world
|
||||
.pilot(&pilot)
|
||||
.inventory
|
||||
.contains_key(&id("base:super_shield"))
|
||||
);
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::Damage {
|
||||
entity: 0,
|
||||
amount: 10,
|
||||
},
|
||||
);
|
||||
assert_eq!(world.player.shield, 90);
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:energy")], 95);
|
||||
collect(&mut world, ®istry, "base:energy");
|
||||
assert_eq!(world.player.shield, 100);
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:energy")], 105);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn additive_pickup_and_script_grants_never_reduce_quantities_above_current_capacity() {
|
||||
let registry = registry();
|
||||
let mut pilot = overflowing();
|
||||
pilot.inventory.insert(id("base:ammo"), 7);
|
||||
let mut world = World::new(&pilot.mission, &pilot, ®istry).unwrap();
|
||||
for item in ["base:ammo", "base:energy", "base:super_shield"] {
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::GiveItem {
|
||||
item: item.into(),
|
||||
count: 1,
|
||||
},
|
||||
);
|
||||
}
|
||||
assert_eq!(world.pilot(&pilot).inventory, pilot.inventory);
|
||||
collect(&mut world, ®istry, "base:ammo");
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:ammo")], 7);
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::ConsumeItem {
|
||||
item: "base:ammo".into(),
|
||||
count: 2,
|
||||
},
|
||||
);
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::GiveItem {
|
||||
item: "base:ammo".into(),
|
||||
count: 1,
|
||||
},
|
||||
);
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:ammo")], 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scripted_consumption_reduces_retained_charge_without_restoring_spent_charge() {
|
||||
let registry = registry();
|
||||
let pilot = overflowing();
|
||||
let mut world = World::new(&pilot.mission, &pilot, ®istry).unwrap();
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::ConsumeItem {
|
||||
item: "base:energy".into(),
|
||||
count: 10,
|
||||
},
|
||||
);
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::ConsumeItem {
|
||||
item: "base:super_shield".into(),
|
||||
count: 110,
|
||||
},
|
||||
);
|
||||
assert_eq!(world.player.shield, 90);
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:energy")], 95);
|
||||
assert_eq!(world.player.super_shield, 0);
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:super_shield")], 15);
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::ConsumeItem {
|
||||
item: "base:super_shield".into(),
|
||||
count: 15,
|
||||
},
|
||||
);
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::ConsumeItem {
|
||||
item: "base:energy".into(),
|
||||
count: 90,
|
||||
},
|
||||
);
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:energy")], 5);
|
||||
assert_eq!(world.super_shield_overflow, 0);
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::Damage {
|
||||
entity: 0,
|
||||
amount: 1,
|
||||
},
|
||||
);
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id("base:super_shield")], 130);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_large_grants_are_split_once_without_duplicating_default_energy() {
|
||||
let mut registry = registry();
|
||||
for item in ["base:energy", "base:super_shield"] {
|
||||
registry.items.get_mut(&id(item)).unwrap().max_count = 200;
|
||||
}
|
||||
let mut pilot = Pilot::default();
|
||||
pilot.inventory.remove(&id("base:energy"));
|
||||
let mut world = World::new(&pilot.mission, &pilot, ®istry).unwrap();
|
||||
for item in ["base:energy", "base:super_shield"] {
|
||||
command(
|
||||
&mut world,
|
||||
®istry,
|
||||
Command::GiveItem {
|
||||
item: item.into(),
|
||||
count: 125,
|
||||
},
|
||||
);
|
||||
assert_eq!(world.pilot(&pilot).inventory[&id(item)], 125);
|
||||
}
|
||||
assert_eq!((world.player.shield, world.player.super_shield), (100, 100));
|
||||
}
|
||||
Reference in new issue
Block a user