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.
This commit is contained in:
2026-04-04 11:53:29 +01:00
parent 196ff9cec4
commit 7cf1b83427
+16 -14
View File
@@ -73,8 +73,7 @@ pub fn job_pathfinding_system(
let mut total_dorfs = 0; let mut total_dorfs = 0;
let mut locked_count = 0; let mut locked_count = 0;
let mut not_standable_count = 0; let mut not_standable_count = 0;
let mut not_idle_count = 0; let mut busy_count = 0; // Truly busy: Active AND non-Idle
let mut active_count = 0;
let candidate_dorfs: Vec<(Entity, IVec3)> = dorf_query let candidate_dorfs: Vec<(Entity, IVec3)> = dorf_query
.iter_mut() .iter_mut()
@@ -92,23 +91,22 @@ pub fn job_pathfinding_system(
return None; 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 current_task = queue.current();
let is_idle = queue.is_empty() let is_idle = queue.is_empty()
|| current_task || current_task
.map(|t| matches!(t, Task::Idle { .. })) .map(|t| matches!(t, Task::Idle { .. }))
.unwrap_or(false); .unwrap_or(false);
if !is_idle { // A dorf is "busy" if they're Active AND doing non-Idle work
not_idle_count += 1; // We can interrupt Idle tasks but not other tasks
return None;
}
// Allow Pending state (about to run) OR Completed/Failed states
// Only exclude Active dorfs (currently executing a task)
let state_val: &TaskState = &*state; let state_val: &TaskState = &*state;
if matches!(state_val, TaskState::Active) { let is_busy = matches!(state_val, TaskState::Active) && !is_idle;
active_count += 1;
if is_busy {
busy_count += 1;
return None; return None;
} }
@@ -117,8 +115,12 @@ pub fn job_pathfinding_system(
.collect(); .collect();
info!( info!(
"[PATHFIND] Dorfs: total={} locked={} not_standable={} not_idle={} active={} candidates={}", "[PATHFIND] Dorfs: total={} locked={} not_standable={} busy={} candidates={}",
total_dorfs, locked_count, not_standable_count, not_idle_count, active_count, candidate_dorfs.len() total_dorfs,
locked_count,
not_standable_count,
busy_count,
candidate_dorfs.len()
); );
if candidate_dorfs.is_empty() { if candidate_dorfs.is_empty() {