From 7cf1b83427cc8073b0fdd80906267d111739a5c3 Mon Sep 17 00:00:00 2001 From: popertots Date: Sat, 4 Apr 2026 11:53:29 +0100 Subject: [PATCH] Fix: Allow dorfs running Idle task to be job candidates The bug: We excluded ALL Active state dorfs, but Idle tasks get immediately promoted from Pending to Active by task_executor_system. So by the time job_pathfinding runs, all dorfs are Active with Idle. The fix: Check if dorf is 'busy' = Active AND non-Idle task. Dorfs with Idle tasks (even in Active state) can be interrupted for real jobs. --- src/entities/tasks/job_pathfinding.rs | 30 ++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/entities/tasks/job_pathfinding.rs b/src/entities/tasks/job_pathfinding.rs index 736f885..049b3c4 100644 --- a/src/entities/tasks/job_pathfinding.rs +++ b/src/entities/tasks/job_pathfinding.rs @@ -73,8 +73,7 @@ pub fn job_pathfinding_system( let mut total_dorfs = 0; let mut locked_count = 0; let mut not_standable_count = 0; - let mut not_idle_count = 0; - let mut active_count = 0; + let mut busy_count = 0; // Truly busy: Active AND non-Idle let candidate_dorfs: Vec<(Entity, IVec3)> = dorf_query .iter_mut() @@ -92,23 +91,22 @@ pub fn job_pathfinding_system( return None; } - // Check if dorf is idle: queue is empty OR current task is Idle + // A dorf is available if: + // 1. Queue is empty, OR + // 2. Current task is Idle (we can replace it) let current_task = queue.current(); let is_idle = queue.is_empty() || current_task .map(|t| matches!(t, Task::Idle { .. })) .unwrap_or(false); - if !is_idle { - not_idle_count += 1; - return None; - } - - // Allow Pending state (about to run) OR Completed/Failed states - // Only exclude Active dorfs (currently executing a task) + // A dorf is "busy" if they're Active AND doing non-Idle work + // We can interrupt Idle tasks but not other tasks let state_val: &TaskState = &*state; - if matches!(state_val, TaskState::Active) { - active_count += 1; + let is_busy = matches!(state_val, TaskState::Active) && !is_idle; + + if is_busy { + busy_count += 1; return None; } @@ -117,8 +115,12 @@ pub fn job_pathfinding_system( .collect(); info!( - "[PATHFIND] Dorfs: total={} locked={} not_standable={} not_idle={} active={} candidates={}", - total_dorfs, locked_count, not_standable_count, not_idle_count, active_count, candidate_dorfs.len() + "[PATHFIND] Dorfs: total={} locked={} not_standable={} busy={} candidates={}", + total_dorfs, + locked_count, + not_standable_count, + busy_count, + candidate_dorfs.len() ); if candidate_dorfs.is_empty() {