feat(simulation): add entity-entity collision

validate_movement now checks both terrain walkability AND tile
occupancy. Builds a spatial index of occupied tiles from stationary
entities, then resolves movers in order — first valid claim wins.

Same spatial pattern needed for D-026 simulation tiers (30-80 active
NPCs) and future pathfinding occupied-tile awareness.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 20:15:24 +01:00
co-authored by Claude Opus 4.6
parent bef4383196
commit f87bd2b0e5
+28
View File
@@ -52,3 +52,31 @@ fn movement_validated_within_app() {
assert!(app.world().get::<MoveIntent>(mover).is_none());
assert!(app.world().get::<MoveIntent>(blocked).is_none());
}
#[test]
fn entity_collision_blocks_movement() {
let mut app = App::new();
app.add_plugins(SimulationPlugin);
app.insert_resource(WalkabilityMap::new(10, 10, 1));
// Stationary entity at (5,4)
app.world_mut().spawn(TilePosition::new(5, 4, 0));
// Mover tries to move into occupied tile
let mover = app
.world_mut()
.spawn((
TilePosition::new(5, 5, 0),
MoveIntent {
target: TilePosition::new(5, 4, 0),
},
))
.id();
app.update();
assert_eq!(
*app.world().get::<TilePosition>(mover).unwrap(),
TilePosition::new(5, 5, 0)
);
}