Task Infrastructure — Task Enum, Queue, Events, Executor

This commit is contained in:
2026-03-22 00:35:22 +00:00
parent 458068fb87
commit d61baaf1ba
9 changed files with 445 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
//! Idle task implementation — wandering behaviour refactored here.
//!
//! This module contains the logic that was previously in the wandering
//! system. Now it's called by the task executor when Task::Idle is active.
use crate::constants::ITILE_SIZE;
use crate::entities::shared_components::Ambulatory;
use crate::entities::tasks::components::Task;
use crate::world::tiles::tilemap::TileMap;
use bevy::prelude::*;
use bevy_rand::prelude::*;
use rand::RngExt;
/// Execute Idle task: set target for wandering, let pathfinding handle movement.
pub(super) fn execute_idle(
entity: Entity,
task: &mut Task,
transform: &Transform,
ambulatory: &mut Ambulatory,
tilemap: &TileMap,
rng: &mut WyRand,
) {
let Task::Idle {
target,
wander_radius,
origin,
} = task
else {
return;
};
let entity_pos = (transform.translation / ITILE_SIZE as f32).as_ivec3();
// If reached target or target is no longer standable, pick new target
if entity_pos == *target || !tilemap.is_standable(*target) {
if let Some(new_target) = pick_wander_target(origin, *wander_radius, tilemap, rng) {
*target = new_target;
}
}
// Set ambulatory target - pathfinding system will compute path
ambulatory.target = Some(Vec3::new(
target.x as f32,
target.y as f32,
transform.translation.z,
));
ambulatory.current_path = None;
ambulatory.path_index = 0;
}
/// Pick a random standable tile within wander radius of origin.
fn pick_wander_target(
origin: &IVec3,
radius: i32,
tilemap: &TileMap,
rng: &mut WyRand,
) -> Option<IVec3> {
let mut candidates = smallvec::SmallVec::<[IVec3; 16]>::new();
// Collect valid tiles within radius
for dx in -radius..=radius {
for dy in -radius..=radius {
let candidate = IVec3::new(
origin.x + dx * ITILE_SIZE,
origin.y + dy * ITILE_SIZE,
origin.z,
);
if tilemap.is_standable(candidate) {
candidates.push(candidate);
}
}
}
if candidates.is_empty() {
return None;
}
let idx = rng.random_range(0..candidates.len());
Some(candidates[idx])
}