aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-10-08 03:24:29 -0500
committermat <git@matdoes.dev>2023-10-08 03:24:29 -0500
commit682609a24e62587094397aab13fda924aa44509e (patch)
tree91770fac7d43c3ac76991af5306453f16d4fa832
parent971f42e3dbee8de614573450fc9548c008f3b3b5 (diff)
downloadazalea-drasl-682609a24e62587094397aab13fda924aa44509e.tar.xz
knockback
-rwxr-xr-xREADME.md2
-rw-r--r--azalea-client/src/packet_handling/game.rs49
-rw-r--r--azalea-entity/src/plugin/indexing.rs3
3 files changed, 50 insertions, 4 deletions
diff --git a/README.md b/README.md
index d7d5a2fa..029e0d43 100755
--- a/README.md
+++ b/README.md
@@ -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