feat(simulation): add tile collision system (#236)
TilePosition component with discrete grid coordinates, flat-storage WalkabilityMap resource with O(1) can_move_to() lookup, MoveIntent component and validate_movement system. Movement validated against walkability map each tick, blocking all NPC and player movement through unwalkable tiles. 11 unit tests + 1 integration test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
use bevy_app::prelude::*;
|
||||
use settled_reach_server::simulation::movement::*;
|
||||
use settled_reach_server::simulation::time::SimulationTime;
|
||||
use settled_reach_server::simulation::SimulationPlugin;
|
||||
|
||||
#[test]
|
||||
fn movement_validated_within_app() {
|
||||
let mut app = App::new();
|
||||
app.add_plugins(SimulationPlugin);
|
||||
|
||||
// Insert a walkability map with one blocked tile
|
||||
let mut map = WalkabilityMap::new(10, 10, 1);
|
||||
map.set_walkable(&TilePosition::new(3, 3, 0), false);
|
||||
app.insert_resource(map);
|
||||
|
||||
// Spawn mover (walkable target) and blocked entity
|
||||
let mover = app
|
||||
.world_mut()
|
||||
.spawn((
|
||||
TilePosition::new(5, 5, 0),
|
||||
MoveIntent {
|
||||
target: TilePosition::new(5, 4, 0),
|
||||
},
|
||||
))
|
||||
.id();
|
||||
|
||||
let blocked = app
|
||||
.world_mut()
|
||||
.spawn((
|
||||
TilePosition::new(3, 4, 0),
|
||||
MoveIntent {
|
||||
target: TilePosition::new(3, 3, 0),
|
||||
},
|
||||
))
|
||||
.id();
|
||||
|
||||
app.update();
|
||||
|
||||
// Mover moved
|
||||
assert_eq!(
|
||||
*app.world().get::<TilePosition>(mover).unwrap(),
|
||||
TilePosition::new(5, 4, 0)
|
||||
);
|
||||
// Blocked stayed
|
||||
assert_eq!(
|
||||
*app.world().get::<TilePosition>(blocked).unwrap(),
|
||||
TilePosition::new(3, 4, 0)
|
||||
);
|
||||
// Tick advanced
|
||||
assert_eq!(app.world().resource::<SimulationTime>().tick, 1);
|
||||
// Both intents consumed
|
||||
assert!(app.world().get::<MoveIntent>(mover).is_none());
|
||||
assert!(app.world().get::<MoveIntent>(blocked).is_none());
|
||||
}
|
||||
Reference in New Issue
Block a user