fix(pathfinding): correct BinaryHeap ordering and movement threshold
- Fix PathNode and ChunkPathNode Ord impl to use correct min-heap ordering (self.f_score.cmp vs other.f_score.cmp) - was causing zig-zag paths - Fix movement threshold formula to use tile_weight directly (walk_speed * tile_weight / 50) instead of inverted multiplier - Update comments to reflect 'higher = slower to traverse' semantics
This commit is contained in:
@@ -155,10 +155,9 @@ struct PathNode {
|
||||
|
||||
impl Ord for PathNode {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
other
|
||||
.f_score
|
||||
.cmp(&self.f_score)
|
||||
.then_with(|| other.g_score.cmp(&self.g_score))
|
||||
self.f_score
|
||||
.cmp(&other.f_score)
|
||||
.then_with(|| self.g_score.cmp(&other.g_score))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,8 +507,7 @@ pub fn movement(mut query: Query<(&mut Ambulatory, &mut Transform)>, tilemap: Re
|
||||
|
||||
if ambulatory.walk_speed > 0. {
|
||||
let tile_weight = get_tile_weight(&tilemap, current_pos.as_ivec3());
|
||||
let speed_multiplier = (tile_weight as f32) / 50.0;
|
||||
let threshold = (ambulatory.walk_speed * speed_multiplier) as u32;
|
||||
let threshold = (ambulatory.walk_speed as i32 * tile_weight as i32 / 50) as u32;
|
||||
|
||||
if ambulatory.step_recovery <= threshold {
|
||||
ambulatory.step_recovery += 1;
|
||||
@@ -557,7 +555,7 @@ fn is_standable_tile(tilemap: &TileMap, pos: IVec3) -> bool {
|
||||
tilemap.is_standable(pos)
|
||||
}
|
||||
|
||||
/// Get the A* weight for a tile position. Lower is better (faster to traverse).
|
||||
/// Get the A* weight for a tile position. Higher = slower to traverse.
|
||||
/// Returns 100 (default) if tile not found.
|
||||
#[inline]
|
||||
fn get_tile_weight(tilemap: &TileMap, pos: IVec3) -> u8 {
|
||||
@@ -566,7 +564,7 @@ fn get_tile_weight(tilemap: &TileMap, pos: IVec3) -> u8 {
|
||||
|
||||
/// Calculate movement cost including tile weight.
|
||||
/// Base costs: cardinal=10, diagonal=14, vertical~50.
|
||||
/// Tile weight adds: (weight - 50) / 5 to make heavier tiles more costly.
|
||||
/// Tile weight adds: (weight - 50) / 5 to make higher-weight tiles more costly.
|
||||
fn calculate_movement_cost(move_dir: IVec3, tile_weight: u8) -> i32 {
|
||||
let base_cost = match (
|
||||
move_dir.x.abs() / ITILE_SIZE,
|
||||
@@ -851,10 +849,9 @@ impl PartialEq for ChunkPathNode {
|
||||
|
||||
impl Ord for ChunkPathNode {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
other
|
||||
.f_score
|
||||
.cmp(&self.f_score)
|
||||
.then_with(|| other.g_score.cmp(&self.g_score))
|
||||
self.f_score
|
||||
.cmp(&other.f_score)
|
||||
.then_with(|| self.g_score.cmp(&other.g_score))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user