fix
This commit is contained in:
@@ -57,7 +57,7 @@ pub fn spawn_log_cargo(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Find nearest free tile from biased position
|
// Find nearest free tile from biased position
|
||||||
let drop_pos = tilemap.find_nearest_free_cargo_tile(biased_pos, 4)?;
|
let drop_pos = tilemap.find_nearest_free_cargo_tile(biased_pos, 4, &[])?;
|
||||||
|
|
||||||
// TODO: OuchEvent — if a living entity occupies drop_pos, they take impact damage.
|
// TODO: OuchEvent — if a living entity occupies drop_pos, they take impact damage.
|
||||||
// Check tilemap occupancy here when the combat/injury system exists.
|
// Check tilemap occupancy here when the combat/injury system exists.
|
||||||
|
|||||||
@@ -283,13 +283,21 @@ pub fn demo_system(
|
|||||||
let idle_dorfs: SmallVec<[Entity; 8]> =
|
let idle_dorfs: SmallVec<[Entity; 8]> =
|
||||||
idle_dorfs.into_iter().map(|(e, _)| e).collect();
|
idle_dorfs.into_iter().map(|(e, _)| e).collect();
|
||||||
|
|
||||||
|
// Track destinations reserved this tick to avoid assigning the same tile
|
||||||
|
// to multiple dorfs before any have physically dropped their cargo.
|
||||||
|
let mut reserved: SmallVec<[IVec3; 8]> = SmallVec::new();
|
||||||
|
|
||||||
for dorf_entity in idle_dorfs {
|
for dorf_entity in idle_dorfs {
|
||||||
// Compute haul destination fresh for each assignment —
|
// Compute haul destination fresh for each assignment,
|
||||||
// as logs accumulate near origin, each new assignment correctly
|
// excluding tiles already reserved this tick.
|
||||||
// finds the next free tile.
|
|
||||||
let dest = tilemap
|
let dest = tilemap
|
||||||
.find_nearest_free_cargo_tile(IVec3::ZERO, HAUL_DEST_SEARCH_RADIUS)
|
.find_nearest_free_cargo_tile(
|
||||||
|
IVec3::ZERO,
|
||||||
|
HAUL_DEST_SEARCH_RADIUS,
|
||||||
|
&reserved,
|
||||||
|
)
|
||||||
.unwrap_or(IVec3::ZERO);
|
.unwrap_or(IVec3::ZERO);
|
||||||
|
reserved.push(dest);
|
||||||
|
|
||||||
let Some((log_entity, log_pos)) = unassigned.pop_front() else {
|
let Some((log_entity, log_pos)) = unassigned.pop_front() else {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ pub fn task_executor_system(
|
|||||||
if chosen_drop.is_none() {
|
if chosen_drop.is_none() {
|
||||||
*chosen_drop = Some(
|
*chosen_drop = Some(
|
||||||
tilemap_mut
|
tilemap_mut
|
||||||
.find_nearest_free_cargo_tile(*dest, 8)
|
.find_nearest_free_cargo_tile(*dest, 8, &[])
|
||||||
.unwrap_or(*dest),
|
.unwrap_or(*dest),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -331,7 +331,7 @@ pub fn task_executor_system(
|
|||||||
if chosen_drop.is_none() {
|
if chosen_drop.is_none() {
|
||||||
*chosen_drop = Some(
|
*chosen_drop = Some(
|
||||||
tilemap_mut
|
tilemap_mut
|
||||||
.find_nearest_free_cargo_tile(*pos, 8)
|
.find_nearest_free_cargo_tile(*pos, 8, &[])
|
||||||
.unwrap_or(*pos),
|
.unwrap_or(*pos),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -467,8 +467,18 @@ impl TileMap {
|
|||||||
/// Uses a spiral outward search — O(radius²) worst case but returns immediately
|
/// Uses a spiral outward search — O(radius²) worst case but returns immediately
|
||||||
/// on first free tile found. Searches only at origin.z (same z-level).
|
/// on first free tile found. Searches only at origin.z (same z-level).
|
||||||
/// Returns None if no free tile found within radius.
|
/// Returns None if no free tile found within radius.
|
||||||
pub fn find_nearest_free_cargo_tile(&self, origin: IVec3, max_radius: i32) -> Option<IVec3> {
|
/// Excludes any tiles in `exclude` from consideration — useful when
|
||||||
if !self.cargo_tiles.contains_key(&origin) && self.is_standable(origin) {
|
/// reserving multiple destinations in the same tick.
|
||||||
|
pub fn find_nearest_free_cargo_tile(
|
||||||
|
&self,
|
||||||
|
origin: IVec3,
|
||||||
|
max_radius: i32,
|
||||||
|
exclude: &[IVec3],
|
||||||
|
) -> Option<IVec3> {
|
||||||
|
if !self.cargo_tiles.contains_key(&origin)
|
||||||
|
&& !exclude.contains(&origin)
|
||||||
|
&& self.is_standable(origin)
|
||||||
|
{
|
||||||
return Some(origin);
|
return Some(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,7 +493,10 @@ impl TileMap {
|
|||||||
origin.y + dy * ITILE_SIZE,
|
origin.y + dy * ITILE_SIZE,
|
||||||
origin.z,
|
origin.z,
|
||||||
);
|
);
|
||||||
if !self.cargo_tiles.contains_key(&candidate) && self.is_standable(candidate) {
|
if !self.cargo_tiles.contains_key(&candidate)
|
||||||
|
&& !exclude.contains(&candidate)
|
||||||
|
&& self.is_standable(candidate)
|
||||||
|
{
|
||||||
return Some(candidate);
|
return Some(candidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user