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:
@@ -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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user