fix
This commit is contained in:
@@ -20,16 +20,15 @@ use crate::world::VisibleGameEntity;
|
|||||||
/// Weight of a single log in kg. Enough to encumber a dorf carrying one.
|
/// Weight of a single log in kg. Enough to encumber a dorf carrying one.
|
||||||
pub const LOG_WEIGHT_KG: u32 = 15;
|
pub const LOG_WEIGHT_KG: u32 = 15;
|
||||||
|
|
||||||
/// Find the standable surface tile at world XY. Returns the tile one above
|
/// Find the standable surface tile at world XY. Returns the floor tile
|
||||||
/// the highest floor tile where an entity can stand, or None if not found.
|
/// 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<IVec3> {
|
fn find_surface_at(world_x: i32, world_y: i32, tilemap: &TileMap) -> Option<IVec3> {
|
||||||
for z in -3i32..=4i32 {
|
for z in -3i32..=4i32 {
|
||||||
let floor_pos = IVec3::new(world_x, world_y, z * ITILE_SIZE);
|
let floor_pos = IVec3::new(world_x, world_y, z * ITILE_SIZE);
|
||||||
if tilemap.floor_tiles.contains_key(&floor_pos) {
|
if tilemap.floor_tiles.contains_key(&floor_pos) && tilemap.is_standable(floor_pos) {
|
||||||
let above = IVec3::new(world_x, world_y, floor_pos.z + ITILE_SIZE);
|
return Some(floor_pos);
|
||||||
if tilemap.is_standable(above) {
|
|
||||||
return Some(above);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -150,54 +150,33 @@ pub fn task_executor_system(
|
|||||||
|
|
||||||
if approach.is_none() {
|
if approach.is_none() {
|
||||||
// First entry: compute approach tile and set target.
|
// First entry: compute approach tile and set target.
|
||||||
// Check 8 surrounding XY positions at the trunk's ground z.
|
// Neighbours at the same z as the trunk base — this IS the floor level.
|
||||||
let offsets = [
|
let trunk_z = trunk_pos.z;
|
||||||
(-1, 0),
|
|
||||||
(1, 0),
|
|
||||||
(0, -1),
|
|
||||||
(0, 1),
|
|
||||||
(-1, -1),
|
|
||||||
(-1, 1),
|
|
||||||
(1, -1),
|
|
||||||
(1, 1),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Find the ground z at the trunk XY (for z reference)
|
// Search expanding outward from the trunk for a standable tile
|
||||||
let ground_z = (-3i32..=4i32)
|
let approach_target = (1..=4).find_map(|radius: i32| {
|
||||||
.find_map(|z| {
|
for dx in -radius..=radius {
|
||||||
let floor_pos =
|
for dy in -radius..=radius {
|
||||||
IVec3::new(trunk_pos.x, trunk_pos.y, z * ITILE_SIZE);
|
// Only check the outer ring of this radius
|
||||||
if tilemap_mut.floor_tiles.contains_key(&floor_pos) {
|
if dx.abs() != radius && dy.abs() != radius {
|
||||||
let above = IVec3::new(
|
continue;
|
||||||
trunk_pos.x,
|
|
||||||
trunk_pos.y,
|
|
||||||
floor_pos.z + ITILE_SIZE,
|
|
||||||
);
|
|
||||||
if tilemap_mut.is_standable(above) {
|
|
||||||
return Some(above.z);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
None
|
|
||||||
})
|
|
||||||
.unwrap_or(trunk_pos.z);
|
|
||||||
|
|
||||||
// Find nearest standable neighbour
|
|
||||||
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,
|
||||||
trunk_pos.y + dy * ITILE_SIZE,
|
trunk_pos.y + dy * ITILE_SIZE,
|
||||||
ground_z,
|
trunk_z,
|
||||||
);
|
);
|
||||||
if tilemap_mut.is_standable(candidate) {
|
if tilemap_mut.is_standable(candidate) {
|
||||||
*approach = Some(candidate);
|
*approach = Some(candidate);
|
||||||
Some(Vec3::new(
|
return Some(Vec3::new(
|
||||||
candidate.x as f32,
|
candidate.x as f32,
|
||||||
candidate.y as f32,
|
candidate.y as f32,
|
||||||
candidate.z as f32 + 1.0,
|
candidate.z as f32 + 1.0,
|
||||||
))
|
));
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
});
|
});
|
||||||
|
|
||||||
match approach_target {
|
match approach_target {
|
||||||
|
|||||||
Reference in New Issue
Block a user