diff options
| author | mat <git@matdoes.dev> | 2023-10-08 03:24:29 -0500 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2023-10-08 03:24:29 -0500 |
| commit | 682609a24e62587094397aab13fda924aa44509e (patch) | |
| tree | 91770fac7d43c3ac76991af5306453f16d4fa832 | |
| parent | 971f42e3dbee8de614573450fc9548c008f3b3b5 (diff) | |
| download | azalea-drasl-682609a24e62587094397aab13fda924aa44509e.tar.xz | |
knockback
| -rwxr-xr-x | README.md | 2 | ||||
| -rw-r--r-- | azalea-client/src/packet_handling/game.rs | 49 | ||||
| -rw-r--r-- | azalea-entity/src/plugin/indexing.rs | 3 |
3 files changed, 50 insertions, 4 deletions
@@ -16,7 +16,7 @@ A collection of Rust crates for making Minecraft bots, clients, and tools. ## Features -- [Accurate physics](https://github.com/azalea-rs/azalea/blob/main/azalea-physics/src/lib.rs) (but some features like knockback and water physics aren't yet implemented) +- [Accurate physics](https://github.com/azalea-rs/azalea/blob/main/azalea-physics/src/lib.rs) (but some features like entity collisions and water physics aren't yet implemented) - [Pathfinder](https://azalea.matdoes.dev/azalea/pathfinder/index.html) - [Swarms](https://azalea.matdoes.dev/azalea/swarm/index.html) - [Breaking blocks](https://azalea.matdoes.dev/azalea/struct.Client.html#method.mine) diff --git a/azalea-client/src/packet_handling/game.rs b/azalea-client/src/packet_handling/game.rs index 46eb21fe..6e138565 100644 --- a/azalea-client/src/packet_handling/game.rs +++ b/azalea-client/src/packet_handling/game.rs @@ -778,8 +778,38 @@ pub fn process_packet_events(ecs: &mut World) { ClientboundGamePacket::UpdateAttributes(_p) => { // debug!("Got update attributes packet {p:?}"); } - ClientboundGamePacket::SetEntityMotion(_p) => { - // debug!("Got entity velocity packet {p:?}"); + ClientboundGamePacket::SetEntityMotion(p) => { + // vanilla servers use this packet for knockback, but note that the Explode + // packet is also sometimes used by servers for knockback + + let mut system_state: SystemState<( + Commands, + Query<(&EntityIdIndex, &InstanceHolder)>, + )> = SystemState::new(ecs); + let (mut commands, mut query) = system_state.get_mut(ecs); + let (entity_id_index, instance_holder) = query.get_mut(player_entity).unwrap(); + + let Some(entity) = entity_id_index.get(&MinecraftEntityId(p.id)) else { + warn!( + "Got set entity motion packet for unknown entity id {}", + p.id + ); + continue; + }; + + commands.entity(entity).add(RelativeEntityUpdate { + partial_world: instance_holder.partial_instance.clone(), + update: Box::new(move |entity| { + let mut physics = entity.get_mut::<Physics>().unwrap(); + physics.delta = Vec3 { + x: p.xa as f64 / 8000., + y: p.ya as f64 / 8000., + z: p.za as f64 / 8000., + }; + }), + }); + + system_state.apply(ecs); } ClientboundGamePacket::SetEntityLink(p) => { debug!("Got set entity link packet {p:?}"); @@ -1154,7 +1184,20 @@ pub fn process_packet_events(ecs: &mut World) { ClientboundGamePacket::Cooldown(_) => {} ClientboundGamePacket::CustomChatCompletions(_) => {} ClientboundGamePacket::DeleteChat(_) => {} - ClientboundGamePacket::Explode(_) => {} + ClientboundGamePacket::Explode(p) => { + trace!("Got explode packet {p:?}"); + let mut system_state: SystemState<Query<&mut Physics>> = SystemState::new(ecs); + let mut query = system_state.get_mut(ecs); + let mut physics = query.get_mut(player_entity).unwrap(); + + physics.delta += Vec3 { + x: p.knockback_x as f64, + y: p.knockback_y as f64, + z: p.knockback_z as f64, + }; + + system_state.apply(ecs); + } ClientboundGamePacket::ForgetLevelChunk(_) => {} ClientboundGamePacket::HorseScreenOpen(_) => {} ClientboundGamePacket::MapItemData(_) => {} diff --git a/azalea-entity/src/plugin/indexing.rs b/azalea-entity/src/plugin/indexing.rs index 297949f6..3ae17f7b 100644 --- a/azalea-entity/src/plugin/indexing.rs +++ b/azalea-entity/src/plugin/indexing.rs @@ -26,6 +26,9 @@ pub struct EntityUuidIndex { /// An index of Minecraft entity IDs to Azalea ECS entities. This is a /// `Component` so local players can keep track of entity IDs independently from /// the instance. +/// +/// If you need a per-instance instead of per-client version of this, you can +/// use [`Instance::entity_by_id`]. #[derive(Component, Default)] pub struct EntityIdIndex { /// An index of entities by their MinecraftEntityId |
