aboutsummaryrefslogtreecommitdiff
path: root/azalea/src/pathfinder/simulation.rs
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-08-25 02:34:31 -0500
committermat <git@matdoes.dev>2023-08-25 02:34:31 -0500
commitd5465cd28e43d48b3e913fdb1161eb907e4d80d0 (patch)
treeb0962ac1bd09b434c67296c038ef3b26245ce6d7 /azalea/src/pathfinder/simulation.rs
parent9c31f8033f006d5f505ce97e359638d6c1136859 (diff)
downloadazalea-drasl-d5465cd28e43d48b3e913fdb1161eb907e4d80d0.tar.xz
add basic pathfinding test
Diffstat (limited to 'azalea/src/pathfinder/simulation.rs')
-rw-r--r--azalea/src/pathfinder/simulation.rs109
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()
+ }
+}