95 lines
2.9 KiB
Rust
95 lines
2.9 KiB
Rust
use bevy::prelude::*;
|
|
|
|
use crate::constants::ITILE_SIZE;
|
|
use crate::entities::behaviour::EntityType;
|
|
use crate::entities::tasks::components::{Task, TaskQueue, TaskState};
|
|
use crate::entities::tasks::job_queue::{JobKind, JobQueue};
|
|
use crate::world::chunks::ChunkMap;
|
|
use crate::world::generation::forestry::TreePart;
|
|
use crate::world::tiles::TileMap;
|
|
|
|
pub fn demo_system(
|
|
mut job_queue: ResMut<JobQueue>,
|
|
tilemap: Res<TileMap>,
|
|
chunk_map: Res<ChunkMap>,
|
|
tree_parts: Query<(Entity, &TreePart)>,
|
|
dorf_query: Query<(&TaskQueue, &TaskState), With<EntityType>>,
|
|
) {
|
|
let any_chopping = dorf_query.iter().any(|(queue, state)| {
|
|
let is_active_or_completing = *state == TaskState::Active || *state == TaskState::Completed;
|
|
if is_active_or_completing {
|
|
if let Some(current) = queue.current() {
|
|
return matches!(current, Task::ChopTree { .. });
|
|
}
|
|
}
|
|
false
|
|
});
|
|
|
|
if !job_queue.has_fell_tree() && !any_chopping {
|
|
if let Some(trunk_pos) = find_tree_nearest_origin(&tilemap, &chunk_map, &tree_parts) {
|
|
job_queue.push(JobKind::FellTree { trunk_pos });
|
|
}
|
|
}
|
|
|
|
if !job_queue.is_empty() {
|
|
let (fell, haul) = job_queue.debug_counts();
|
|
info!("[QUEUE] FellTree: {}, HaulCargo: {}", fell, haul);
|
|
}
|
|
}
|
|
|
|
fn find_tree_nearest_origin(
|
|
tilemap: &TileMap,
|
|
chunk_map: &ChunkMap,
|
|
tree_parts: &Query<(Entity, &TreePart)>,
|
|
) -> Option<IVec3> {
|
|
let origin = IVec3::ZERO;
|
|
let mut best_xy: Option<(IVec2, i32)> = None;
|
|
|
|
for (_, part) in tree_parts.iter() {
|
|
if !part.is_trunk {
|
|
continue;
|
|
}
|
|
if !tilemap.fixture_tiles.contains_key(&part.tile_pos) {
|
|
continue;
|
|
}
|
|
|
|
let chunk = crate::world::chunks::world_to_chunk(part.tile_pos);
|
|
let loaded = chunk_map.loaded_chunks.contains_key(&(chunk + IVec2::X))
|
|
&& chunk_map.loaded_chunks.contains_key(&(chunk - IVec2::X))
|
|
&& chunk_map.loaded_chunks.contains_key(&(chunk + IVec2::Y))
|
|
&& chunk_map.loaded_chunks.contains_key(&(chunk - IVec2::Y));
|
|
if !loaded {
|
|
continue;
|
|
}
|
|
|
|
let dx = (part.tile_pos.x - origin.x).abs() / ITILE_SIZE;
|
|
let dy = (part.tile_pos.y - origin.y).abs() / ITILE_SIZE;
|
|
let dist = dx.max(dy);
|
|
|
|
if best_xy.map_or(true, |(_, best_dist)| dist < best_dist) {
|
|
best_xy = Some((part.tile_pos.xy(), dist));
|
|
}
|
|
}
|
|
|
|
let Some((nearest_xy, _)) = best_xy else {
|
|
return None;
|
|
};
|
|
|
|
let lowest_trunk = tree_parts
|
|
.iter()
|
|
.filter_map(|(_, p)| {
|
|
if p.is_trunk
|
|
&& p.tile_pos.x == nearest_xy.x
|
|
&& p.tile_pos.y == nearest_xy.y
|
|
&& tilemap.fixture_tiles.contains_key(&p.tile_pos)
|
|
{
|
|
Some(p.tile_pos)
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.min_by_key(|pos| pos.z);
|
|
|
|
lowest_trunk
|
|
}
|