From 36328360163b845a79493f58636c222bd809d705 Mon Sep 17 00:00:00 2001 From: popertots Date: Sun, 22 Mar 2026 22:30:15 +0000 Subject: [PATCH] fix --- src/entities/cargo/log.rs | 13 ++++--- src/entities/tasks/executor.rs | 65 ++++++++++++---------------------- 2 files changed, 28 insertions(+), 50 deletions(-) diff --git a/src/entities/cargo/log.rs b/src/entities/cargo/log.rs index 0a29844..70aff81 100644 --- a/src/entities/cargo/log.rs +++ b/src/entities/cargo/log.rs @@ -20,16 +20,15 @@ use crate::world::VisibleGameEntity; /// Weight of a single log in kg. Enough to encumber a dorf carrying one. pub const LOG_WEIGHT_KG: u32 = 15; -/// Find the standable surface tile at world XY. Returns the tile one above -/// the highest floor tile where an entity can stand, or None if not found. +/// Find the standable surface tile at world XY. Returns the floor tile +/// where an entity can stand, or None if not found. +/// The standable position IS the floor tile itself (has can_stand_in=true), +/// not the air above it. fn find_surface_at(world_x: i32, world_y: i32, tilemap: &TileMap) -> Option { for z in -3i32..=4i32 { let floor_pos = IVec3::new(world_x, world_y, z * ITILE_SIZE); - if tilemap.floor_tiles.contains_key(&floor_pos) { - let above = IVec3::new(world_x, world_y, floor_pos.z + ITILE_SIZE); - if tilemap.is_standable(above) { - return Some(above); - } + if tilemap.floor_tiles.contains_key(&floor_pos) && tilemap.is_standable(floor_pos) { + return Some(floor_pos); } } None diff --git a/src/entities/tasks/executor.rs b/src/entities/tasks/executor.rs index 2039946..61a9782 100644 --- a/src/entities/tasks/executor.rs +++ b/src/entities/tasks/executor.rs @@ -150,54 +150,33 @@ pub fn task_executor_system( 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), - (1, 0), - (0, -1), - (0, 1), - (-1, -1), - (-1, 1), - (1, -1), - (1, 1), - ]; + // Neighbours at the same z as the trunk base — this IS the floor level. + let trunk_z = trunk_pos.z; - // Find the ground z at the trunk XY (for z reference) - let ground_z = (-3i32..=4i32) - .find_map(|z| { - let floor_pos = - IVec3::new(trunk_pos.x, trunk_pos.y, z * ITILE_SIZE); - if tilemap_mut.floor_tiles.contains_key(&floor_pos) { - let above = IVec3::new( - trunk_pos.x, - trunk_pos.y, - floor_pos.z + ITILE_SIZE, + // Search expanding outward from the trunk for a standable tile + let approach_target = (1..=4).find_map(|radius: i32| { + for dx in -radius..=radius { + for dy in -radius..=radius { + // Only check the outer ring of this radius + if dx.abs() != radius && dy.abs() != radius { + continue; + } + let candidate = IVec3::new( + trunk_pos.x + dx * ITILE_SIZE, + trunk_pos.y + dy * ITILE_SIZE, + trunk_z, ); - if tilemap_mut.is_standable(above) { - return Some(above.z); + if tilemap_mut.is_standable(candidate) { + *approach = Some(candidate); + return Some(Vec3::new( + candidate.x as f32, + candidate.y as f32, + candidate.z as f32 + 1.0, + )); } } - None - }) - .unwrap_or(trunk_pos.z); - - // Find nearest standable neighbour - let approach_target = offsets.iter().find_map(|(dx, dy)| { - let candidate = IVec3::new( - trunk_pos.x + dx * ITILE_SIZE, - trunk_pos.y + dy * ITILE_SIZE, - ground_z, - ); - if tilemap_mut.is_standable(candidate) { - *approach = Some(candidate); - Some(Vec3::new( - candidate.x as f32, - candidate.y as f32, - candidate.z as f32 + 1.0, - )) - } else { - None } + None }); match approach_target {