This commit is contained in:
2026-03-22 16:05:38 +00:00
parent bceec18a7a
commit e7a43457a3
3 changed files with 50 additions and 24 deletions
+21 -16
View File
@@ -26,7 +26,7 @@ use smallvec::SmallVec;
use std::collections::VecDeque;
use crate::constants::ITILE_SIZE;
use crate::entities::cargo::{Cargo, Haulable};
use crate::entities::cargo::{Cargo, HaulSlot, Haulable};
use crate::entities::tasks::components::{
ChopStep, HaulStep, Task, TaskQueue, TaskState, CHOP_TICKS_DEFAULT,
};
@@ -53,17 +53,14 @@ pub enum DemoState {
/// Tree has been felled. Working through the haul queue.
///
/// `unassigned` — logs not yet claimed, ordered nearest-to-origin first.
/// `in_progress` — log entities currently assigned to a dorf.
///
/// Each tick: assign idle dorfs from unassigned. When a log entity
/// disappears from cargo_tiles it has been dropped at destination —
/// remove it from in_progress. When both are empty, go Idle.
/// `in_progress` — dorf entities currently executing a HaulCargo task for this tree.
/// A dorf is removed when they return to idle (log dropped, task complete).
Hauling {
felled_trunk_pos: IVec3,
/// Queue of (log_entity, log_tile_pos) not yet assigned.
/// Front = highest priority (nearest to origin).
unassigned: VecDeque<(Entity, IVec3)>,
/// Log entities currently being hauled by a dorf.
/// Dorf entities currently hauling a log for this tree.
in_progress: FxHashSet<Entity>,
},
}
@@ -83,6 +80,7 @@ pub fn demo_system(
chunk_map: Res<ChunkMap>,
tree_parts: Query<(Entity, &TreePart)>,
cargo_query: Query<(Entity, &Cargo), With<Haulable>>,
haul_slot_query: Query<&HaulSlot>,
mut dorf_query: Query<(Entity, &mut TaskQueue, &mut TaskState, &Transform)>,
) {
match &mut *demo_state {
@@ -139,11 +137,20 @@ pub fn demo_system(
.unwrap_or(trunk_pos);
// Find one idle dorf — prefer closest to the tree.
// Don't interrupt a dorf still carrying cargo.
let mut best_dorf: Option<(Entity, i32)> = None;
for (entity, queue, state, transform) in dorf_query.iter() {
if !is_idle_dorf(&queue, &state) {
continue;
}
// Skip dorfs still carrying cargo
if haul_slot_query
.get(entity)
.map(|h| h.is_occupied())
.unwrap_or(false)
{
continue;
}
let pos = transform.translation.as_ivec3();
let dx = (pos.x - lowest_trunk.x).abs() / ITILE_SIZE;
let dy = (pos.y - lowest_trunk.y).abs() / ITILE_SIZE;
@@ -252,14 +259,12 @@ pub fn demo_system(
} => {
let felled_trunk_pos = *felled_trunk_pos;
// Remove completed hauls from in_progress —
// a log is done when it's no longer in cargo_tiles (picked up by dorf).
// This is correct: once picked up, the haul is committed from demo's perspective.
in_progress.retain(|&log_entity| {
cargo_query
.get(log_entity)
.map(|(_, cargo)| tilemap.cargo_tiles.contains_key(&cargo.tile_pos))
.unwrap_or(false)
// Remove dorfs that have returned to idle — their haul is complete
in_progress.retain(|&dorf_entity| {
dorf_query
.get(dorf_entity)
.map(|(_, queue, state, _)| !is_idle_dorf(queue, state))
.unwrap_or(false) // entity gone = treat as done
});
// Assign idle dorfs to unassigned logs
@@ -318,7 +323,7 @@ pub fn demo_system(
step: HaulStep::MovingToCargo,
});
*state = TaskState::Pending;
in_progress.insert(log_entity);
in_progress.insert(dorf_entity);
} else {
// Couldn't assign — put log back at front of queue
unassigned.push_front((log_entity, log_pos));
+1 -1
View File
@@ -185,7 +185,7 @@ pub fn task_executor_system(
if fall_dir == Vec2::ZERO {
fall_dir = Vec2::new(1.0, 0.0); // default: fall east
}
let log_sprite = asset_server.load("tree_trunk.png");
let log_sprite: Handle<Image> = asset_server.load("log_cargo.png");
for &pos in trunk_positions.iter() {
crate::entities::cargo::spawn_log_cargo(
&mut commands,