From 57764fbcbb106945dcd2b622bde5aae95c0f210e Mon Sep 17 00:00:00 2001 From: popertots Date: Sun, 22 Mar 2026 22:05:08 +0000 Subject: [PATCH] fix --- src/entities/tasks/components.rs | 3 +- src/entities/tasks/demo.rs | 2 +- src/entities/tasks/executor.rs | 53 ++++++++++++++++++++------------ 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/entities/tasks/components.rs b/src/entities/tasks/components.rs index 43194cb..71a4b4a 100644 --- a/src/entities/tasks/components.rs +++ b/src/entities/tasks/components.rs @@ -43,7 +43,8 @@ pub enum IdleState { #[derive(Clone, Debug, PartialEq)] pub enum ChopStep { /// Walking to within range of the trunk. - MovingToTree, + /// `approach` is the computed standable tile adjacent to the trunk (impassable). + MovingToTree { approach: Option }, /// Entity is in range and actively chopping. Chopping { ticks_remaining: u32 }, /// Chopping complete. diff --git a/src/entities/tasks/demo.rs b/src/entities/tasks/demo.rs index aa0a982..ada4e72 100644 --- a/src/entities/tasks/demo.rs +++ b/src/entities/tasks/demo.rs @@ -181,7 +181,7 @@ pub fn demo_system( queue.push(Task::ChopTree { trunk_pos: lowest_trunk, chop_ticks: CHOP_TICKS_DEFAULT, - step: ChopStep::MovingToTree, + step: ChopStep::MovingToTree { approach: None }, }); *state = TaskState::Pending; } diff --git a/src/entities/tasks/executor.rs b/src/entities/tasks/executor.rs index 725d65c..2039946 100644 --- a/src/entities/tasks/executor.rs +++ b/src/entities/tasks/executor.rs @@ -135,7 +135,7 @@ pub fn task_executor_system( chop_ticks, step, } => match step { - ChopStep::MovingToTree => { + ChopStep::MovingToTree { ref mut approach } => { if !tilemap_mut.fixture_tiles.contains_key(trunk_pos) { failed_writer.write(TaskFailed { entity, @@ -145,11 +145,11 @@ pub fn task_executor_system( *state = TaskState::Failed; continue; } - if ambulatory.target.is_none() { - use crate::constants::ITILE_SIZE; - // The trunk tile itself is impassable (can_stand_in=false). - // Path to the nearest standable tile adjacent to the trunk instead. + use crate::constants::ITILE_SIZE; + + if approach.is_none() { + // First entry: compute approach tile and set target. // Check 8 surrounding XY positions at the trunk's ground z. let offsets = [ (-1, 0), @@ -162,7 +162,7 @@ pub fn task_executor_system( (1, 1), ]; - // First find the ground z at the trunk XY (for z reference) + // Find the ground z at the trunk XY (for z reference) let ground_z = (-3i32..=4i32) .find_map(|z| { let floor_pos = @@ -181,7 +181,7 @@ pub fn task_executor_system( }) .unwrap_or(trunk_pos.z); - // Find nearest standable neighbour to path toward + // Find nearest standable neighbour let approach_target = offsets.iter().find_map(|(dx, dy)| { let candidate = IVec3::new( trunk_pos.x + dx * ITILE_SIZE, @@ -189,6 +189,7 @@ pub fn task_executor_system( ground_z, ); if tilemap_mut.is_standable(candidate) { + *approach = Some(candidate); Some(Vec3::new( candidate.x as f32, candidate.y as f32, @@ -205,7 +206,6 @@ pub fn task_executor_system( ambulatory.current_path = None; } None => { - // No adjacent standable tile — tree may be surrounded failed_writer.write(TaskFailed { entity, task: current_task.clone(), @@ -215,19 +215,32 @@ pub fn task_executor_system( continue; } } + } else if ambulatory.target.is_none() { + // Arrived at approach tile (or path failed and target cleared). + // Check distance to trunk; if close enough, start chopping. + let dx = transform.translation.x - trunk_pos.x as f32; + let dy = transform.translation.y - trunk_pos.y as f32; + let dist_sq = dx * dx + dy * dy; + let chop_range_sq = + (ITILE_SIZE as f32 * 2.5) * (ITILE_SIZE as f32 * 2.5); + + if dist_sq <= chop_range_sq { + // Close enough — transition to chopping + ambulatory.current_path = None; + *step = ChopStep::Chopping { + ticks_remaining: *chop_ticks, + }; + } else if let Some(approach_tile) = *approach { + // Not in range — re-set target to approach tile + ambulatory.target = Some(Vec3::new( + approach_tile.x as f32, + approach_tile.y as f32, + approach_tile.z as f32 + 1.0, + )); + ambulatory.current_path = None; + } } - let dx = transform.translation.x - trunk_pos.x as f32; - let dy = transform.translation.y - trunk_pos.y as f32; - let dist_sq = dx * dx + dy * dy; - let chop_range_sq = (crate::constants::TILE_SIZE * 2.5) - * (crate::constants::TILE_SIZE * 2.5); - if dist_sq <= chop_range_sq { - ambulatory.target = None; - ambulatory.current_path = None; - *step = ChopStep::Chopping { - ticks_remaining: *chop_ticks, - }; - } + // If target is Some, pathfinding is handling movement — nothing to do } ChopStep::Chopping { ticks_remaining } => { if *ticks_remaining == 0 {