Files
dorf/src/entities/livestock/pig.rs
T
popertots 49f91de0c9 feat(pathfinding): implement Phase 3 reactive pathing
- Add validation_cooldown field to Ambulatory component
- Implement validate_next_steps to check walkability of next 3 path nodes
- Integrate validation into movement system (every 10 frames)
- Trigger re-path when validation fails (path blocked or invalid)
- Entities now detect and recover from invalid paths automatically
2026-03-18 21:33:38 +00:00

104 lines
3.1 KiB
Rust

use crate::constants::TILE_SIZE;
use crate::constants::*;
use crate::entities::item::{spawn_prefab, MiscPrefab};
use crate::entities::shared_components::Ambulatory;
use crate::world::tiles::tilemap;
use crate::world::VisibleGameEntity;
use bevy::prelude::*;
use bevy_rand::prelude::*;
use rand::RngExt;
#[derive(Bundle)]
pub struct Pig {
ambulatory: Ambulatory,
sprite: Sprite,
transform: Transform,
visibility: Visibility,
drop_timer: PigDropTimer,
}
impl Pig {
pub fn new(asset_server: &Res<AssetServer>, position: Vec3) -> Self {
Pig {
ambulatory: Ambulatory {
walk_speed: 25.,
run_speed: 6.,
target: None,
current_path: None,
path_index: 0,
step_recovery: 0,
validation_cooldown: 0,
},
sprite: Sprite {
image: asset_server.load("pig.png"),
..Default::default()
},
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
visibility: Visibility::Hidden,
drop_timer: PigDropTimer(Timer::from_seconds(5.0, TimerMode::Repeating)), // NEW
}
}
}
#[derive(Component, Deref, DerefMut)]
pub struct PigDropTimer(pub Timer);
pub fn spawn_pigs(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut rng_q: Query<&mut WyRand, With<GlobalRng>>,
) {
if let Ok(mut rng) = rng_q.single_mut() {
for _ in 0..5 {
let pig = commands
.spawn(Pig::new(
&asset_server,
Vec3::new(
rng.random_range(-32.0f32..32.0f32).round(),
rng.random_range(-32.0f32..32.0f32).round(),
35.0,
) * TILE_SIZE,
))
.id();
commands.entity(pig).insert(VisibleGameEntity);
}
}
}
pub fn pig_drop_system(
mut commands: Commands,
asset_server: Res<AssetServer>,
time: Res<Time>,
mut pigs: Query<(&mut PigDropTimer, &Transform)>,
mut tilemap: ResMut<tilemap::TileMap>,
mut rng_q: Query<&mut WyRand, With<GlobalRng>>,
) {
for (mut timer, transform) in &mut pigs {
timer.tick(time.delta());
if timer.just_finished() {
if let Ok(mut rng) = rng_q.single_mut() {
if rng.random_range(0..10) <= 5 {
// Example: pig drops raw meat
spawn_prefab(
&mut commands,
&asset_server,
MiscPrefab::RawMeat,
transform.translation,
&mut tilemap,
);
} else {
//example: pig drops a coin
spawn_prefab(
&mut commands,
&asset_server,
MiscPrefab::Coin,
transform.translation,
&mut tilemap,
);
}
}
}
}
}