diff options
Diffstat (limited to 'azalea-physics/src/lib.rs')
| -rw-r--r-- | azalea-physics/src/lib.rs | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs index 0a8f8a8b..e3954061 100644 --- a/azalea-physics/src/lib.rs +++ b/azalea-physics/src/lib.rs @@ -5,37 +5,38 @@ pub mod collision; use azalea_block::{Block, BlockState}; use azalea_core::{BlockPos, Vec3}; -use azalea_ecs::{ - app::{App, Plugin}, - entity::Entity, - event::{EventReader, EventWriter}, - query::With, - schedule::IntoSystemDescriptor, - system::{Query, Res}, - AppTickExt, -}; use azalea_world::{ entity::{ metadata::Sprinting, move_relative, Attributes, Jumping, Local, Physics, Position, WorldName, }, - World, WorldContainer, + Instance, WorldContainer, +}; +use bevy_app::{App, CoreSchedule, IntoSystemAppConfigs, Plugin}; +use bevy_ecs::{ + entity::Entity, + event::{EventReader, EventWriter}, + query::With, + schedule::{IntoSystemConfig, IntoSystemConfigs, SystemSet}, + system::{Query, Res}, }; use collision::{move_colliding, MoverType}; +/// A Bevy [`SystemSet`] for running physics that makes entities do things. +#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] +pub struct PhysicsSet; + pub struct PhysicsPlugin; impl Plugin for PhysicsPlugin { fn build(&self, app: &mut App) { app.add_event::<ForceJumpEvent>() - .add_system( - force_jump_listener - .label("force_jump_listener") - .after("walk_listener") - .after("sprint_listener") - .before(azalea_world::entity::update_bounding_box), - ) - .add_tick_system(travel.label("travel").after(ai_step)) - .add_tick_system(ai_step.label("ai_step")); + .add_system(force_jump_listener.before(azalea_world::entity::update_bounding_box)) + .add_systems( + (ai_step, travel) + .chain() + .in_set(PhysicsSet) + .in_schedule(CoreSchedule::FixedUpdate), + ); } } @@ -156,7 +157,7 @@ pub fn ai_step( /// Jump even if we aren't on the ground. pub struct ForceJumpEvent(pub Entity); -fn force_jump_listener( +pub fn force_jump_listener( mut query: Query<(&mut Physics, &Position, &Sprinting, &WorldName)>, world_container: Res<WorldContainer>, mut events: EventReader<ForceJumpEvent>, @@ -201,7 +202,7 @@ fn get_block_pos_below_that_affects_movement(position: &Position) -> BlockPos { fn handle_relative_friction_and_calculate_movement( block_friction: f32, - world: &World, + world: &Instance, physics: &mut Physics, position: &mut Position, attributes: &Attributes, @@ -251,7 +252,7 @@ fn get_friction_influenced_speed(physics: &Physics, attributes: &Attributes, fri /// Returns the what the entity's jump should be multiplied by based on the /// block they're standing on. -fn block_jump_factor(world: &World, position: &Position) -> f32 { +fn block_jump_factor(world: &Instance, position: &Position) -> f32 { let block_at_pos = world.chunks.get_block_state(&position.into()); let block_below = world .chunks @@ -279,7 +280,7 @@ fn block_jump_factor(world: &World, position: &Position) -> f32 { // public double getJumpBoostPower() { // return this.hasEffect(MobEffects.JUMP) ? (double)(0.1F * // (float)(this.getEffect(MobEffects.JUMP).getAmplifier() + 1)) : 0.0D; } -fn jump_power(world: &World, position: &Position) -> f32 { +fn jump_power(world: &Instance, position: &Position) -> f32 { 0.42 * block_jump_factor(world, position) } @@ -303,22 +304,21 @@ mod tests { use super::*; use azalea_core::{ChunkPos, ResourceLocation}; - use azalea_ecs::{app::App, TickPlugin}; use azalea_world::{ entity::{EntityBundle, EntityPlugin, MinecraftEntityId}, Chunk, PartialWorld, }; + use bevy_app::App; + use bevy_time::fixed_timestep::FixedTime; use uuid::Uuid; /// You need an app to spawn entities in the world and do updates. fn make_test_app() -> App { let mut app = App::new(); - app.add_plugin(TickPlugin { - tick_interval: Duration::ZERO, - }) - .add_plugin(PhysicsPlugin) - .add_plugin(EntityPlugin) - .init_resource::<WorldContainer>(); + app.add_plugin(PhysicsPlugin) + .add_plugin(EntityPlugin) + .insert_resource(FixedTime::new(Duration::from_millis(50))) + .init_resource::<WorldContainer>(); app } @@ -353,6 +353,7 @@ mod tests { // y should start at 70 assert_eq!(entity_pos.y, 70.); } + app.world.run_schedule(CoreSchedule::FixedUpdate); app.update(); { let entity_pos = *app.world.get::<Position>(entity).unwrap(); @@ -361,6 +362,7 @@ mod tests { let entity_physics = app.world.get::<Physics>(entity).unwrap().clone(); assert!(entity_physics.delta.y < 0.); } + app.world.run_schedule(CoreSchedule::FixedUpdate); app.update(); { let entity_pos = *app.world.get::<Position>(entity).unwrap(); @@ -413,6 +415,7 @@ mod tests { block_state.is_some(), "Block state should exist, if this fails that means the chunk wasn't loaded and the block didn't get placed" ); + app.world.run_schedule(CoreSchedule::FixedUpdate); app.update(); { let entity_pos = *app.world.get::<Position>(entity).unwrap(); @@ -421,6 +424,7 @@ mod tests { let entity_physics = app.world.get::<Physics>(entity).unwrap().clone(); assert!(entity_physics.delta.y < 0.); } + app.world.run_schedule(CoreSchedule::FixedUpdate); app.update(); { let entity_pos = *app.world.get::<Position>(entity).unwrap(); @@ -476,6 +480,7 @@ mod tests { ); // do a few steps so we fall on the slab for _ in 0..20 { + app.world.run_schedule(CoreSchedule::FixedUpdate); app.update(); } let entity_pos = app.world.get::<Position>(entity).unwrap(); @@ -528,6 +533,7 @@ mod tests { ); // do a few steps so we fall on the slab for _ in 0..20 { + app.world.run_schedule(CoreSchedule::FixedUpdate); app.update(); } let entity_pos = app.world.get::<Position>(entity).unwrap(); @@ -584,6 +590,7 @@ mod tests { ); // do a few steps so we fall on the wall for _ in 0..20 { + app.world.run_schedule(CoreSchedule::FixedUpdate); app.update(); } @@ -645,6 +652,7 @@ mod tests { ); // do a few steps so we fall on the wall for _ in 0..20 { + app.world.run_schedule(CoreSchedule::FixedUpdate); app.update(); } |
