valence_equipment/
interaction_broadcast.rs
1use valence_inventory::{HeldItem, Inventory, PlayerAction};
2use valence_server::entity::living::LivingFlags;
3use valence_server::event_loop::PacketEvent;
4use valence_server::interact_item::InteractItemEvent;
5use valence_server::protocol::packets::play::PlayerActionC2s;
6use valence_server::ItemKind;
7
8use super::*;
9
10#[derive(Debug, Default, Clone, Component)]
13pub struct EquipmentInteractionBroadcast;
14
15pub(crate) fn start_interaction(
18 mut clients: Query<
19 (&Inventory, &HeldItem, &mut LivingFlags),
20 (With<Client>, With<EquipmentInteractionBroadcast>),
21 >,
22 mut events: EventReader<InteractItemEvent>,
23) {
24 for event in events.read() {
25 if let Ok((inv, held_item, mut flags)) = clients.get_mut(event.client) {
26 let item = inv.slot(held_item.slot()).item;
27 let has_arrows = inv.first_slot_with_item(ItemKind::Arrow, i8::MAX).is_some();
28 if (item == ItemKind::Bow && !has_arrows)
29 || (item == ItemKind::Crossbow
30 && !has_arrows
31 && inv.slot(45).item != ItemKind::FireworkRocket)
32 {
33 continue;
34 }
35 flags.set_using_item(true);
36 }
37 }
38}
39
40pub(crate) fn stop_interaction(
43 mut clients: Query<&mut LivingFlags, (With<Client>, With<EquipmentInteractionBroadcast>)>,
44 mut packets: EventReader<PacketEvent>,
45) {
46 for packet in packets.read() {
47 if let Some(pkt) = packet.decode::<PlayerActionC2s>() {
48 if pkt.action == PlayerAction::ReleaseUseItem {
49 if let Ok(mut flags) = clients.get_mut(packet.client) {
50 flags.set_using_item(false);
51 }
52 }
53 }
54 }
55}