valence/crates/valence_client/src/interact_entity.rs
Ryan Johnson c5557e744d
Move packets out of valence_core. (#335)
## Description

- Move all packets out of `valence_core` and into the places where
they're actually used. This has a few benefits:
- Avoids compiling code for packets that go unused when feature flags
are disabled.
- Code is distributed more uniformly across crates, improving
compilation times.
- Improves local reasoning when everything relevant to a module is
defined in the same place.
  - Easier to share code between the packet consumer and the packet.
- Tweak `Packet` macro syntax.
- Update `syn` to 2.0.
- Reorganize some code in `valence_client` (needs further work).
- Impl `WritePacket` for `Instance`.
- Remove packet enums such as `S2cPlayPacket` and `C2sPlayPacket`.
- Replace `assert_packet_count` and `assert_packet_order` macros with
non-macro methods.
To prevent this PR from getting out of hand, I've disabled the packet
inspector and stresser until they have been rewritten to account for
these changes.
2023-05-29 01:36:11 -07:00

67 lines
2 KiB
Rust

use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use glam::Vec3;
use valence_core::hand::Hand;
use valence_core::protocol::var_int::VarInt;
use valence_core::protocol::{packet_id, Decode, Encode, Packet};
use valence_entity::EntityManager;
use crate::event_loop::{EventLoopSchedule, EventLoopSet, PacketEvent};
pub(super) fn build(app: &mut App) {
app.add_event::<InteractEntityEvent>().add_system(
handle_interact_entity
.in_schedule(EventLoopSchedule)
.in_base_set(EventLoopSet::PreUpdate),
);
}
#[derive(Copy, Clone, Debug)]
pub struct InteractEntityEvent {
pub client: Entity,
/// The entity being interacted with.
pub entity: Entity,
/// If the client was sneaking during the interaction.
pub sneaking: bool,
/// The kind of interaction that occurred.
pub interact: EntityInteraction,
}
#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)]
pub enum EntityInteraction {
Interact(Hand),
Attack,
InteractAt { target: Vec3, hand: Hand },
}
fn handle_interact_entity(
mut packets: EventReader<PacketEvent>,
entities: Res<EntityManager>,
mut events: EventWriter<InteractEntityEvent>,
) {
for packet in packets.iter() {
if let Some(pkt) = packet.decode::<PlayerInteractEntityC2s>() {
// TODO: check that the entity is in the same instance as the player.
// TODO: check that the distance between the player and the interacted entity is
// within some configurable tolerance level.
if let Some(entity) = entities.get_by_id(pkt.entity_id.0) {
events.send(InteractEntityEvent {
client: packet.client,
entity,
sneaking: pkt.sneaking,
interact: pkt.interact,
})
}
}
}
}
#[derive(Copy, Clone, Debug, Encode, Decode, Packet)]
#[packet(id = packet_id::PLAYER_INTERACT_ENTITY_C2S)]
pub struct PlayerInteractEntityC2s {
pub entity_id: VarInt,
pub interact: EntityInteraction,
pub sneaking: bool,
}