feat(pathfinding): implement Phase 3 reactive pathing
- Add validation_cooldown field to Ambulatory component - Implement validate_next_steps to check walkability of next 3 path nodes - Integrate validation into movement system (every 10 frames) - Trigger re-path when validation fails (path blocked or invalid) - Entities now detect and recover from invalid paths automatically
This commit is contained in:
@@ -27,6 +27,7 @@ impl Pig {
|
|||||||
current_path: None,
|
current_path: None,
|
||||||
path_index: 0,
|
path_index: 0,
|
||||||
step_recovery: 0,
|
step_recovery: 0,
|
||||||
|
validation_cooldown: 0,
|
||||||
},
|
},
|
||||||
sprite: Sprite {
|
sprite: Sprite {
|
||||||
image: asset_server.load("pig.png"),
|
image: asset_server.load("pig.png"),
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ impl Rabbit {
|
|||||||
current_path: None,
|
current_path: None,
|
||||||
path_index: 0,
|
path_index: 0,
|
||||||
step_recovery: 0,
|
step_recovery: 0,
|
||||||
|
validation_cooldown: 0,
|
||||||
},
|
},
|
||||||
sprite: Sprite {
|
sprite: Sprite {
|
||||||
image: asset_server.load("rabbit.png"),
|
image: asset_server.load("rabbit.png"),
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ impl Dorf {
|
|||||||
current_path: None,
|
current_path: None,
|
||||||
path_index: 0,
|
path_index: 0,
|
||||||
step_recovery: 0,
|
step_recovery: 0,
|
||||||
|
validation_cooldown: 0,
|
||||||
},
|
},
|
||||||
sprite: Sprite {
|
sprite: Sprite {
|
||||||
image: asset_server.load("dorf.png"),
|
image: asset_server.load("dorf.png"),
|
||||||
|
|||||||
@@ -9,6 +9,21 @@ pub struct Ambulatory {
|
|||||||
pub path_index: usize,
|
pub path_index: usize,
|
||||||
pub target: Option<Vec3>,
|
pub target: Option<Vec3>,
|
||||||
pub step_recovery: u32,
|
pub step_recovery: u32,
|
||||||
|
pub validation_cooldown: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Ambulatory {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
walk_speed: 1.0,
|
||||||
|
run_speed: 2.0,
|
||||||
|
current_path: None,
|
||||||
|
path_index: 0,
|
||||||
|
target: None,
|
||||||
|
step_recovery: 0,
|
||||||
|
validation_cooldown: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
|
|||||||
@@ -502,6 +502,17 @@ pub fn movement(mut query: Query<(&mut Ambulatory, &mut Transform)>, tilemap: Re
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ambulatory.validation_cooldown > 0 {
|
||||||
|
ambulatory.validation_cooldown -= 1;
|
||||||
|
} else if let Some(path) = &ambulatory.current_path {
|
||||||
|
if !validate_next_steps(&tilemap, path, ambulatory.path_index, 3) {
|
||||||
|
ambulatory.current_path = None;
|
||||||
|
ambulatory.validation_cooldown = 10;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ambulatory.validation_cooldown = 10;
|
||||||
|
}
|
||||||
|
|
||||||
if ambulatory.walk_speed > 0. {
|
if ambulatory.walk_speed > 0. {
|
||||||
if ambulatory.step_recovery <= ambulatory.walk_speed as u32 {
|
if ambulatory.step_recovery <= ambulatory.walk_speed as u32 {
|
||||||
ambulatory.step_recovery += 1;
|
ambulatory.step_recovery += 1;
|
||||||
@@ -534,6 +545,17 @@ pub fn movement(mut query: Query<(&mut Ambulatory, &mut Transform)>, tilemap: Re
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate_next_steps(tilemap: &TileMap, path: &[Vec3], start_index: usize, steps: usize) -> bool {
|
||||||
|
let end = (start_index + steps).min(path.len());
|
||||||
|
for i in start_index..end {
|
||||||
|
let pos = path[i].as_ivec3();
|
||||||
|
if !is_standable_tile(tilemap, pos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn is_standable_tile(tilemap: &TileMap, pos: IVec3) -> bool {
|
fn is_standable_tile(tilemap: &TileMap, pos: IVec3) -> bool {
|
||||||
let can_stand_in_tile = tilemap
|
let can_stand_in_tile = tilemap
|
||||||
.floor_tiles
|
.floor_tiles
|
||||||
|
|||||||
Reference in New Issue
Block a user