fix
This commit is contained in:
@@ -43,7 +43,8 @@ pub enum IdleState {
|
|||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum ChopStep {
|
pub enum ChopStep {
|
||||||
/// Walking to within range of the trunk.
|
/// Walking to within range of the trunk.
|
||||||
MovingToTree,
|
/// `approach` is the computed standable tile adjacent to the trunk (impassable).
|
||||||
|
MovingToTree { approach: Option<IVec3> },
|
||||||
/// Entity is in range and actively chopping.
|
/// Entity is in range and actively chopping.
|
||||||
Chopping { ticks_remaining: u32 },
|
Chopping { ticks_remaining: u32 },
|
||||||
/// Chopping complete.
|
/// Chopping complete.
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ pub fn demo_system(
|
|||||||
queue.push(Task::ChopTree {
|
queue.push(Task::ChopTree {
|
||||||
trunk_pos: lowest_trunk,
|
trunk_pos: lowest_trunk,
|
||||||
chop_ticks: CHOP_TICKS_DEFAULT,
|
chop_ticks: CHOP_TICKS_DEFAULT,
|
||||||
step: ChopStep::MovingToTree,
|
step: ChopStep::MovingToTree { approach: None },
|
||||||
});
|
});
|
||||||
*state = TaskState::Pending;
|
*state = TaskState::Pending;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ pub fn task_executor_system(
|
|||||||
chop_ticks,
|
chop_ticks,
|
||||||
step,
|
step,
|
||||||
} => match step {
|
} => match step {
|
||||||
ChopStep::MovingToTree => {
|
ChopStep::MovingToTree { ref mut approach } => {
|
||||||
if !tilemap_mut.fixture_tiles.contains_key(trunk_pos) {
|
if !tilemap_mut.fixture_tiles.contains_key(trunk_pos) {
|
||||||
failed_writer.write(TaskFailed {
|
failed_writer.write(TaskFailed {
|
||||||
entity,
|
entity,
|
||||||
@@ -145,11 +145,11 @@ pub fn task_executor_system(
|
|||||||
*state = TaskState::Failed;
|
*state = TaskState::Failed;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ambulatory.target.is_none() {
|
|
||||||
use crate::constants::ITILE_SIZE;
|
|
||||||
|
|
||||||
// The trunk tile itself is impassable (can_stand_in=false).
|
use crate::constants::ITILE_SIZE;
|
||||||
// Path to the nearest standable tile adjacent to the trunk instead.
|
|
||||||
|
if approach.is_none() {
|
||||||
|
// First entry: compute approach tile and set target.
|
||||||
// Check 8 surrounding XY positions at the trunk's ground z.
|
// Check 8 surrounding XY positions at the trunk's ground z.
|
||||||
let offsets = [
|
let offsets = [
|
||||||
(-1, 0),
|
(-1, 0),
|
||||||
@@ -162,7 +162,7 @@ pub fn task_executor_system(
|
|||||||
(1, 1),
|
(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)
|
let ground_z = (-3i32..=4i32)
|
||||||
.find_map(|z| {
|
.find_map(|z| {
|
||||||
let floor_pos =
|
let floor_pos =
|
||||||
@@ -181,7 +181,7 @@ pub fn task_executor_system(
|
|||||||
})
|
})
|
||||||
.unwrap_or(trunk_pos.z);
|
.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 approach_target = offsets.iter().find_map(|(dx, dy)| {
|
||||||
let candidate = IVec3::new(
|
let candidate = IVec3::new(
|
||||||
trunk_pos.x + dx * ITILE_SIZE,
|
trunk_pos.x + dx * ITILE_SIZE,
|
||||||
@@ -189,6 +189,7 @@ pub fn task_executor_system(
|
|||||||
ground_z,
|
ground_z,
|
||||||
);
|
);
|
||||||
if tilemap_mut.is_standable(candidate) {
|
if tilemap_mut.is_standable(candidate) {
|
||||||
|
*approach = Some(candidate);
|
||||||
Some(Vec3::new(
|
Some(Vec3::new(
|
||||||
candidate.x as f32,
|
candidate.x as f32,
|
||||||
candidate.y as f32,
|
candidate.y as f32,
|
||||||
@@ -205,7 +206,6 @@ pub fn task_executor_system(
|
|||||||
ambulatory.current_path = None;
|
ambulatory.current_path = None;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// No adjacent standable tile — tree may be surrounded
|
|
||||||
failed_writer.write(TaskFailed {
|
failed_writer.write(TaskFailed {
|
||||||
entity,
|
entity,
|
||||||
task: current_task.clone(),
|
task: current_task.clone(),
|
||||||
@@ -215,19 +215,32 @@ pub fn task_executor_system(
|
|||||||
continue;
|
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;
|
// If target is Some, pathfinding is handling movement — nothing to do
|
||||||
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,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ChopStep::Chopping { ticks_remaining } => {
|
ChopStep::Chopping { ticks_remaining } => {
|
||||||
if *ticks_remaining == 0 {
|
if *ticks_remaining == 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user