aboutsummaryrefslogtreecommitdiff
path: root/azalea-physics
diff options
context:
space:
mode:
Diffstat (limited to 'azalea-physics')
-rw-r--r--azalea-physics/Cargo.toml12
-rw-r--r--azalea-physics/src/collision/mod.rs8
-rw-r--r--azalea-physics/src/collision/world_collisions.rs8
-rw-r--r--azalea-physics/src/lib.rs68
4 files changed, 53 insertions, 43 deletions
diff --git a/azalea-physics/Cargo.toml b/azalea-physics/Cargo.toml
index 9305080b..dd579471 100644
--- a/azalea-physics/Cargo.toml
+++ b/azalea-physics/Cargo.toml
@@ -9,13 +9,15 @@ version = "0.6.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-azalea-block = {path = "../azalea-block", version = "^0.6.0"}
-azalea-core = {path = "../azalea-core", version = "^0.6.0"}
-azalea-ecs = {version = "0.6.0", path = "../azalea-ecs"}
-azalea-registry = {path = "../azalea-registry", version = "^0.6.0"}
-azalea-world = {path = "../azalea-world", version = "^0.6.0"}
+azalea-block = { path = "../azalea-block", version = "^0.6.0" }
+azalea-core = { path = "../azalea-core", version = "^0.6.0" }
+azalea-registry = { path = "../azalea-registry", version = "^0.6.0" }
+azalea-world = { path = "../azalea-world", version = "^0.6.0" }
+bevy_app = "0.10.0"
+bevy_ecs = "0.10.0"
once_cell = "1.16.0"
parking_lot = "^0.12.1"
[dev-dependencies]
+bevy_time = "0.10.0"
uuid = "^1.1.2"
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index 7d934020..53efd2fe 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -7,7 +7,7 @@ mod world_collisions;
use azalea_core::{Axis, Vec3, AABB, EPSILON};
use azalea_world::{
entity::{self},
- MoveEntityError, World,
+ Instance, MoveEntityError,
};
pub use blocks::BlockWithShape;
pub use discrete_voxel_shape::*;
@@ -52,7 +52,7 @@ pub enum MoverType {
// return var4;
// }
-fn collide(movement: &Vec3, world: &World, physics: &entity::Physics) -> Vec3 {
+fn collide(movement: &Vec3, world: &Instance, physics: &entity::Physics) -> Vec3 {
let entity_bounding_box = physics.bounding_box;
// TODO: get_entity_collisions
// let entity_collisions = world.get_entity_collisions(self,
@@ -73,7 +73,7 @@ fn collide(movement: &Vec3, world: &World, physics: &entity::Physics) -> Vec3 {
pub fn move_colliding(
_mover_type: &MoverType,
movement: &Vec3,
- world: &World,
+ world: &Instance,
position: &mut entity::Position,
physics: &mut entity::Physics,
) -> Result<(), MoveEntityError> {
@@ -186,7 +186,7 @@ pub fn move_colliding(
fn collide_bounding_box(
movement: &Vec3,
entity_bounding_box: &AABB,
- world: &World,
+ world: &Instance,
entity_collisions: Vec<VoxelShape>,
) -> Vec3 {
let mut collision_boxes: Vec<VoxelShape> = Vec::with_capacity(entity_collisions.len() + 1);
diff --git a/azalea-physics/src/collision/world_collisions.rs b/azalea-physics/src/collision/world_collisions.rs
index 9ffc62a5..aa55150e 100644
--- a/azalea-physics/src/collision/world_collisions.rs
+++ b/azalea-physics/src/collision/world_collisions.rs
@@ -2,16 +2,16 @@ use super::Shapes;
use crate::collision::{BlockWithShape, VoxelShape, AABB};
use azalea_block::BlockState;
use azalea_core::{ChunkPos, ChunkSectionPos, Cursor3d, CursorIterationType, EPSILON};
-use azalea_world::{Chunk, World};
+use azalea_world::{Chunk, Instance};
use parking_lot::RwLock;
use std::sync::Arc;
-pub fn get_block_collisions(world: &World, aabb: AABB) -> BlockCollisions<'_> {
+pub fn get_block_collisions(world: &Instance, aabb: AABB) -> BlockCollisions<'_> {
BlockCollisions::new(world, aabb)
}
pub struct BlockCollisions<'a> {
- pub world: &'a World,
+ pub world: &'a Instance,
pub aabb: AABB,
pub entity_shape: VoxelShape,
pub cursor: Cursor3d,
@@ -19,7 +19,7 @@ pub struct BlockCollisions<'a> {
}
impl<'a> BlockCollisions<'a> {
- pub fn new(world: &'a World, aabb: AABB) -> Self {
+ pub fn new(world: &'a Instance, aabb: AABB) -> Self {
let origin_x = (aabb.min_x - EPSILON).floor() as i32 - 1;
let origin_y = (aabb.min_y - EPSILON).floor() as i32 - 1;
let origin_z = (aabb.min_z - EPSILON).floor() as i32 - 1;
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();
}