diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2022-08-29 20:41:01 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-29 20:41:01 -0500 |
| commit | f42d630544165d11a544224ac273d6aaf89d8095 (patch) | |
| tree | 94bd73771ecb582d89a87cdca8e21b2d6573ef12 /azalea-physics/src/lib.rs | |
| parent | 2ea804401f54a45765860201d10d0569d07862ec (diff) | |
| download | azalea-drasl-f42d630544165d11a544224ac273d6aaf89d8095.tar.xz | |
Physics (#11)
* Put physics module in azalea-entity
* port aabb
* add more stuff to PositionXYZ
* azalea-physics
* important collision things
* more physics stuff
* backup because i'm about to delete shapes
* more shape stuff
* CubeVoxelShape
* no compile errors???
insane
* impl VoxelShape for ArrayVoxelShape
* Shapes stuff
* collide_x but it doesn't work yet
* binary_search
* it compiles
* Entity has bounding box
* Update discrete_voxel_shape.rs
* Entity::make_bounding_box
* ok i'm about to merge az-entity and az-world
might be a terrible idea which is why i'm committing first
* ok so i moved entity to world
* on_pos and move_entity compiles
* add send_position
* move collision stuff to collision module in az-physics
* dimension is no longer an Option
* start trying to do collision for the client
* collision works :tada:
* start adding palette resizing
* get_and_set (pain)
* it compiles but probably won't work
* add a test
* remove printlns
* add more tests for palette stuff
* ClientboundMoveVec3Packet -> ClientboundMoveEntityPosPacket
i think i changed this on accident once
* palette resizing works
todo: remove the printlns
* Remove printlns in palette.rs
* fix issues from merge
* fixes + work a bit more on physics
* Better entities (#19)
* well it compiles
* add tests to entity storage
* add suggestions in azalea-brigadier
* this probably causes ub
* fix brigadiersuggestions
* get rid of entityid
* test From<EntityMut> for EntityRef
* don't mention other libraries since there's too many
* fix warnings
* do todos in brigadier suggestions
* work on physics
* more physics stuff
* remove trait feature on az-block
i think rust gets confused and compiles the macro without the feature
* bump ahash
* aes tests in az-crypto
* optimize aes's deps
* fix crashes
* fix section_index for negative numbers and test
* fix BlockPos protocol implementation
* remove some debug prints
* prepare to add ai_step
* make ai step work
* clippy
Diffstat (limited to 'azalea-physics/src/lib.rs')
| -rw-r--r-- | azalea-physics/src/lib.rs | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs new file mode 100644 index 00000000..8842727b --- /dev/null +++ b/azalea-physics/src/lib.rs @@ -0,0 +1,127 @@ +pub mod collision; + +use azalea_block::Block; +use azalea_core::{BlockPos, Vec3}; +use azalea_world::entity::{EntityData, EntityMut}; +use collision::{MovableEntity, MoverType}; + +pub trait HasPhysics { + fn travel(&mut self, acceleration: &Vec3); + fn ai_step(&mut self); +} + +impl HasPhysics for EntityMut<'_> { + /// Move the entity with the given acceleration while handling friction, + /// gravity, collisions, and some other stuff. + fn travel(&mut self, acceleration: &Vec3) { + // if !self.is_effective_ai() && !self.is_controlled_by_local_instance() { + // // this.calculateEntityAnimation(this, this instanceof FlyingAnimal); + // return; + // } + + let gravity: f64 = 0.08; + + // TODO: slow falling effect + // let is_falling = self.delta.y <= 0.; + + // TODO: fluids + + // TODO: elytra + + let block_pos_below = get_block_pos_below_that_affects_movement(self); + let block_friction = + if let Some(block_state_below) = self.dimension.get_block_state(&block_pos_below) { + let block_below: Box<dyn Block> = block_state_below.into(); + block_below.behavior().friction + } else { + unreachable!("Block below should be a real block.") + }; + + let inertia = if self.on_ground { + block_friction * 0.91 + } else { + 0.91 + }; + let mut movement = + handle_relative_friction_and_calculate_movement(self, acceleration, block_friction); + + movement.y -= gravity; + + // if (this.shouldDiscardFriction()) { + // this.setDeltaMovement(movement.x, yMovement, movement.z); + // } else { + // this.setDeltaMovement(movement.x * (double)inertia, yMovement * 0.9800000190734863D, movement.z * (double)inertia); + // } + + // if should_discard_friction(self) { + if false { + self.delta = movement; + } else { + self.delta = Vec3 { + x: movement.x * inertia as f64, + y: movement.y * 0.98f64, + z: movement.z * inertia as f64, + }; + } + } + + /// applies air resistance, calls self.travel(), and some other random + /// stuff. + fn ai_step(&mut self) { + // vanilla does movement interpolation here, doesn't really matter much for a bot though + + self.xxa *= 0.98; + self.zza *= 0.98; + + self.travel(&Vec3 { + x: self.xxa as f64, + y: self.yya as f64, + z: self.zza as f64, + }); + // freezing + // pushEntities + // drowning damage + } +} + +fn get_block_pos_below_that_affects_movement(entity: &EntityData) -> BlockPos { + BlockPos::new( + entity.pos().x as i32, + // TODO: this uses bounding_box.min_y instead of position.y + (entity.pos().y - 0.5f64) as i32, + entity.pos().z as i32, + ) +} + +fn handle_relative_friction_and_calculate_movement( + entity: &mut EntityMut, + acceleration: &Vec3, + block_friction: f32, +) -> Vec3 { + entity.move_relative(get_speed(&*entity, block_friction), acceleration); + // entity.delta = entity.handle_on_climbable(entity.delta); + entity + .move_colliding(&MoverType::Own, &entity.delta.clone()) + .expect("Entity should exist."); + // let delta_movement = entity.delta; + // if ((entity.horizontalCollision || entity.jumping) && (entity.onClimbable() || entity.getFeetBlockState().is(Blocks.POWDER_SNOW) && PowderSnowBlock.canEntityWalkOnPowderSnow(entity))) { + // var3 = new Vec3(var3.x, 0.2D, var3.z); + // } + // TODO: powdered snow + + entity.delta +} + +// private float getFrictionInfluencedSpeed(float friction) { +// return this.onGround ? this.getSpeed() * (0.21600002F / (friction * friction * friction)) : this.flyingSpeed; +// } +fn get_speed(entity: &EntityData, friction: f32) -> f32 { + // TODO: have speed & flying_speed fields in entity + if entity.on_ground { + let speed: f32 = 0.7; + speed * (0.216f32 / (friction * friction * friction)) + } else { + // entity.flying_speed + 0.02 + } +} |
