fix: four interlocking pathfinding bugs causing panic, failure, and yo-yo teleportation
1. CSV Overflow Panic: Use saturating_sub to prevent underflow when total_failed_paths > n 2. Heuristic Scale Mismatch: octile_distance_3d now divides by ITILE_SIZE to match g-score units 3. Goal Z Offset: Correct target.as_ivec3() - ivec3(0,0,1) not ITILE_SIZE (target already has +1.0) 4. Gravity Yo-Yo: Clear current_path and target when entity falls to prevent teleportation loop
This commit is contained in:
+1900
File diff suppressed because it is too large
Load Diff
@@ -183,8 +183,8 @@ pub fn prepare_paths(
|
||||
continue;
|
||||
};
|
||||
let start = transform.translation.as_ivec3();
|
||||
let goal = target.as_ivec3() - ivec3(0, 0, ITILE_SIZE);
|
||||
let distance = octile_distance_3d(start, goal) / ITILE_SIZE;
|
||||
let goal = target.as_ivec3() - ivec3(0, 0, 1);
|
||||
let distance = octile_distance_3d(start, goal);
|
||||
|
||||
if distance <= PATHFINDER_SHORT_PATH_MAX_TILES {
|
||||
let path = calculate_path_benchmarked(&tilemap, start, goal);
|
||||
@@ -352,6 +352,8 @@ pub fn movement(mut query: Query<(&mut Ambulatory, &mut Transform)>, tilemap: Re
|
||||
let current_pos = transform.translation;
|
||||
if !is_standable_tile(&tilemap, current_pos.as_ivec3()) {
|
||||
transform.translation.z -= TILE_SIZE;
|
||||
ambulatory.current_path = None;
|
||||
ambulatory.target = None;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -433,9 +435,9 @@ fn calculate_movement_cost(move_dir: IVec3) -> i32 {
|
||||
}
|
||||
|
||||
fn octile_distance_3d(a: IVec3, b: IVec3) -> i32 {
|
||||
let dx = (a.x - b.x).abs();
|
||||
let dy = (a.y - b.y).abs();
|
||||
let dz = (a.z - b.z).abs();
|
||||
let dx = (a.x - b.x).abs() / ITILE_SIZE;
|
||||
let dy = (a.y - b.y).abs() / ITILE_SIZE;
|
||||
let dz = (a.z - b.z).abs() / ITILE_SIZE;
|
||||
let (dmax, dmid, dmin) = sorted_desc(dx, dy, dz);
|
||||
10 * dmax + 4 * dmid + dmin
|
||||
}
|
||||
@@ -767,7 +769,7 @@ fn write_benchmark_csv(bench: &PathfindingBenchmark, filename: &str) -> std::io:
|
||||
let duration = bench.path_calc_times_us.get(i).copied().unwrap_or(0);
|
||||
let length = bench.path_lengths.get(i).copied().unwrap_or(0);
|
||||
let nodes = bench.nodes_expanded.get(i).copied().unwrap_or(0);
|
||||
let success = i < (n - bench.total_failed_paths as usize);
|
||||
let success = i < n.saturating_sub(bench.total_failed_paths as usize);
|
||||
writeln!(file, "{},{},{},{},{}", i, duration, length, nodes, success)?;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user