From 087e056bbcb91a2b8a1c90d5dd3fe571b6632ee8 Mon Sep 17 00:00:00 2001 From: Ryan <16417098+Stankye@users.noreply.github.com> Date: Mon, 21 Nov 2022 21:20:09 -0800 Subject: [PATCH] feat: PlayerCombatKill client event (#44) * feat: PlayerCombatKill client event * Event name changed to Death * dead client state and respawn packet * fix doc comment --- azalea-client/src/client.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 9c941abf..675f8bec 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -7,6 +7,7 @@ use azalea_protocol::{ connect::{Connection, ConnectionError, ReadConnection, WriteConnection}, packets::{ game::{ + clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, serverbound_client_information_packet::ServerboundClientInformationPacket, serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, @@ -64,6 +65,8 @@ pub enum Event { Packet(Box), /// Happens when a player is added, removed, or updated in the tab list. UpdatePlayers(UpdatePlayersEvent), + /// Emits when the player dies. + Death(Option>), } /// Happens when a player is added, removed, or updated in the tab list. @@ -102,6 +105,7 @@ pub struct Client { pub world: Arc>, pub physics_state: Arc>, pub client_information: Arc>, + pub dead: Arc>, /// Plugins are a way for other crates to add custom functionality to the /// client and keep state. If you're not making a plugin and you're using /// the `azalea` crate. you can ignore this field. @@ -280,6 +284,7 @@ impl Client { world: Arc::new(RwLock::new(World::default())), physics_state: Arc::new(Mutex::new(PhysicsState::default())), client_information: Arc::new(RwLock::new(ClientInformation::default())), + dead: Arc::new(Mutex::new(false)), // The plugins can be modified by the user by replacing the plugins // field right after this. No Mutex so the user doesn't need to .lock(). plugins: Arc::new(Plugins::new()), @@ -753,6 +758,13 @@ impl Client { } ClientboundGamePacket::SetHealth(p) => { debug!("Got set health packet {:?}", p); + if p.health == 0.0 { + let mut dead_lock = client.dead.lock(); + if !*dead_lock { + *dead_lock = true; + tx.send(Event::Death(None)).unwrap(); + } + } } ClientboundGamePacket::SetExperience(p) => { debug!("Got set experience packet {:?}", p); @@ -877,11 +889,25 @@ impl Client { ClientboundGamePacket::PlayerChatHeader(_) => {} ClientboundGamePacket::PlayerCombatEnd(_) => {} ClientboundGamePacket::PlayerCombatEnter(_) => {} - ClientboundGamePacket::PlayerCombatKill(_) => {} + ClientboundGamePacket::PlayerCombatKill(p) => { + debug!("Got player kill packet {:?}", p); + if *client.entity_id.read() == p.player_id { + let mut dead_lock = client.dead.lock(); + if !*dead_lock { + *dead_lock = true; + tx.send(Event::Death(Some(Box::new(p.clone())))).unwrap(); + } + } + } ClientboundGamePacket::PlayerLookAt(_) => {} ClientboundGamePacket::RemoveMobEffect(_) => {} ClientboundGamePacket::ResourcePack(_) => {} - ClientboundGamePacket::Respawn(_) => {} + ClientboundGamePacket::Respawn(p) => { + debug!("Got respawn packet {:?}", p); + // Sets clients dead state to false. + let mut dead_lock = client.dead.lock(); + *dead_lock = false; + } ClientboundGamePacket::SelectAdvancementsTab(_) => {} ClientboundGamePacket::SetActionBarText(_) => {} ClientboundGamePacket::SetBorderCenter(_) => {}