diff options
| author | mat <git@matdoes.dev> | 2023-08-25 02:34:31 -0500 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2023-08-25 02:34:31 -0500 |
| commit | d5465cd28e43d48b3e913fdb1161eb907e4d80d0 (patch) | |
| tree | b0962ac1bd09b434c67296c038ef3b26245ce6d7 /azalea/src/pathfinder/simulation.rs | |
| parent | 9c31f8033f006d5f505ce97e359638d6c1136859 (diff) | |
| download | azalea-drasl-d5465cd28e43d48b3e913fdb1161eb907e4d80d0.tar.xz | |
add basic pathfinding test
Diffstat (limited to 'azalea/src/pathfinder/simulation.rs')
| -rw-r--r-- | azalea/src/pathfinder/simulation.rs | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/azalea/src/pathfinder/simulation.rs b/azalea/src/pathfinder/simulation.rs new file mode 100644 index 00000000..372a8a3b --- /dev/null +++ b/azalea/src/pathfinder/simulation.rs @@ -0,0 +1,109 @@ +use std::{sync::Arc, time::Duration}; + +use azalea_client::PhysicsState; +use azalea_core::{ResourceLocation, Vec3}; +use azalea_entity::{ + attributes::AttributeInstance, metadata::Sprinting, Attributes, EntityDimensions, Physics, + Position, +}; +use azalea_world::{ChunkStorage, Instance, InstanceContainer, InstanceName, MinecraftEntityId}; +use bevy_app::{App, FixedUpdate}; +use bevy_ecs::prelude::*; +use bevy_time::fixed_timestep::FixedTime; +use parking_lot::RwLock; + +#[derive(Bundle, Clone)] +pub struct SimulatedPlayerBundle { + pub position: Position, + pub physics: Physics, + pub physics_state: PhysicsState, + pub attributes: Attributes, +} + +impl SimulatedPlayerBundle { + pub fn new(position: Vec3) -> Self { + let dimensions = EntityDimensions { + width: 0.6, + height: 1.8, + }; + + SimulatedPlayerBundle { + position: Position::new(position), + physics: Physics::new(dimensions, &position), + physics_state: PhysicsState::default(), + attributes: Attributes { + speed: AttributeInstance::new(0.1), + attack_speed: AttributeInstance::new(4.0), + }, + } + } +} + +/// Simulate the Minecraft world to see if certain movements would be possible. +pub struct Simulation { + pub app: App, + pub entity: Entity, + _instance: Arc<RwLock<Instance>>, +} + +impl Simulation { + pub fn new(chunks: ChunkStorage, player: SimulatedPlayerBundle) -> Self { + let instance_name = ResourceLocation::new("azalea:simulation"); + + let instance = Arc::new(RwLock::new(Instance { + chunks, + ..Default::default() + })); + + let mut app = App::new(); + // we don't use all the default azalea plugins because we don't need all of them + app.add_plugins(( + azalea_physics::PhysicsPlugin, + azalea_entity::EntityPlugin, + azalea_client::movement::PlayerMovePlugin, + super::PathfinderPlugin, + crate::BotPlugin, + azalea_client::task_pool::TaskPoolPlugin::default(), + )) + // make sure it doesn't do fixed ticks without us telling it to + .insert_resource(FixedTime::new(Duration::from_secs(60))) + .insert_resource(InstanceContainer { + worlds: [(instance_name.clone(), Arc::downgrade(&instance.clone()))] + .iter() + .cloned() + .collect(), + }); + + app.edit_schedule(bevy_app::Main, |schedule| { + schedule.set_executor_kind(bevy_ecs::schedule::ExecutorKind::SingleThreaded); + }); + + let entity = app + .world + .spawn(( + MinecraftEntityId(0), + InstanceName(instance_name), + azalea_entity::Local, + azalea_client::LocalPlayerInLoadedChunk, + azalea_entity::Jumping::default(), + azalea_entity::LookDirection::default(), + Sprinting(true), + azalea_entity::metadata::Player, + player, + )) + .id(); + + Self { + app, + entity, + _instance: instance, + } + } + pub fn tick(&mut self) { + self.app.world.run_schedule(FixedUpdate); + self.app.update(); + } + pub fn position(&self) -> Vec3 { + **self.app.world.get::<Position>(self.entity).unwrap() + } +} |
