- 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
104 lines
3.1 KiB
Rust
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,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|