1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

update_hit_result_component

This commit is contained in:
mat 2023-03-11 22:33:07 -06:00
parent 34f647781f
commit babb0d3a74
12 changed files with 86 additions and 54 deletions

View file

@ -444,8 +444,8 @@ impl Client {
pub fn world(&self) -> Arc<RwLock<Instance>> {
let world_name = self.component::<WorldName>();
let ecs = self.ecs.lock();
let world_container = ecs.resource::<InstanceContainer>();
world_container.get(&world_name).unwrap()
let instance_container = ecs.resource::<InstanceContainer>();
instance_container.get(&world_name).unwrap()
}
/// Returns whether we have a received the login packet yet.

View file

@ -1,15 +1,24 @@
use azalea_core::{BlockPos, Direction, GameMode};
use azalea_core::{BlockHitResult, BlockPos, Direction, GameMode, Vec3};
use azalea_physics::clip::{BlockShapeType, ClipContext, FluidPickType};
use azalea_protocol::packets::game::{
serverbound_interact_packet::InteractionHand,
serverbound_use_item_on_packet::{BlockHitResult, ServerboundUseItemOnPacket},
serverbound_use_item_on_packet::{BlockHit, ServerboundUseItemOnPacket},
};
use azalea_world::{
entity::{view_vector, EyeHeight, LookDirection, Position, WorldName},
InstanceContainer,
};
use azalea_world::entity::{view_vector, EyeHeight, LookDirection, Position};
use bevy_app::{App, Plugin};
use bevy_ecs::{component::Component, entity::Entity, event::EventReader, system::Query};
use bevy_ecs::{
component::Component,
entity::Entity,
event::EventReader,
system::{Query, Res},
};
use derive_more::{Deref, DerefMut};
use log::warn;
use crate::{local_player::LocalGameMode, Client, LocalPlayer, PlayerInfo};
use crate::{local_player::LocalGameMode, Client, LocalPlayer};
/// A plugin that allows clients to interact with blocks in the world.
pub struct InteractPlugin;
@ -73,7 +82,7 @@ fn handle_block_interact_event(
local_player.write_packet(
ServerboundUseItemOnPacket {
hand: InteractionHand::MainHand,
block_hit: BlockHitResult {
block_hit: BlockHit {
block_pos: event.position,
direction: Direction::Up,
location: event.position.center(),
@ -93,15 +102,38 @@ fn update_hit_result_component(
&Position,
&EyeHeight,
&LookDirection,
&WorldName,
)>,
instance_container: Res<InstanceContainer>,
) {
for (hit_result, game_mode, position, eye_height, look_direction) in &mut query {
for (mut hit_result_ref, game_mode, position, eye_height, look_direction, world_name) in
&mut query
{
let pick_range = if game_mode.current == GameMode::Creative {
6.
} else {
4.5
};
let view_vector = view_vector(look_direction);
let end_position = **position + view_vector * pick_range;
let eye_position = Vec3 {
x: position.x,
y: position.y + **eye_height as f64,
z: position.z,
};
let end_position = eye_position + view_vector * pick_range;
let instance_lock = instance_container
.get(world_name)
.expect("entities must always be in a valid world");
let instance = instance_lock.read();
let hit_result = azalea_physics::clip::clip(
&instance.chunks,
ClipContext {
from: eye_position,
to: end_position,
block_shape_type: BlockShapeType::Outline,
fluid_pick_type: FluidPickType::None,
},
);
**hit_result_ref = hit_result;
}
}

View file

@ -195,7 +195,7 @@ fn process_packet_events(ecs: &mut World) {
)>,
ResMut<InstanceContainer>,
)> = SystemState::new(ecs);
let (mut commands, mut query, mut world_container) = system_state.get_mut(ecs);
let (mut commands, mut query, mut instance_container) = system_state.get_mut(ecs);
let (mut local_player, world_name, game_profile, client_information) =
query.get_mut(player_entity).unwrap();
@ -221,16 +221,16 @@ fn process_packet_events(ecs: &mut World) {
.entity(player_entity)
.insert(WorldName(new_world_name.clone()));
}
// add this world to the world_container (or don't if it's already
// add this world to the instance_container (or don't if it's already
// there)
let weak_world = world_container.insert(
let weak_world = instance_container.insert(
new_world_name.clone(),
dimension.height,
dimension.min_y,
);
// set the partial_world to an empty world
// (when we add chunks or entities those will be in the
// world_container)
// instance_container)
*local_player.partial_instance.write() = PartialInstance::new(
client_information.view_distance.into(),

View file

@ -10,9 +10,9 @@ use crate::collision::{BlockWithShape, VoxelShape};
pub struct ClipContext {
pub from: Vec3,
pub to: Vec3,
pub block: BlockShapeGetter,
pub fluid: CanPickFluid,
pub collision_context: EntityCollisionContext,
pub block_shape_type: BlockShapeType,
pub fluid_pick_type: FluidPickType,
// pub collision_context: EntityCollisionContext,
}
impl ClipContext {
// minecraft passes in the world and blockpos here... but it doesn't actually
@ -20,24 +20,24 @@ impl ClipContext {
pub fn block_shape(&self, block_state: BlockState) -> &VoxelShape {
// TODO: implement the other shape getters
// (see the ClipContext.Block class in the vanilla source)
match self.block {
BlockShapeGetter::Collider => block_state.shape(),
BlockShapeGetter::Outline => block_state.shape(),
BlockShapeGetter::Visual => block_state.shape(),
BlockShapeGetter::FallDamageResetting => block_state.shape(),
match self.block_shape_type {
BlockShapeType::Collider => block_state.shape(),
BlockShapeType::Outline => block_state.shape(),
BlockShapeType::Visual => block_state.shape(),
BlockShapeType::FallDamageResetting => block_state.shape(),
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum BlockShapeGetter {
pub enum BlockShapeType {
Collider,
Outline,
Visual,
FallDamageResetting,
}
#[derive(Debug, Copy, Clone)]
pub enum CanPickFluid {
pub enum FluidPickType {
None,
SourceOnly,
Any,
@ -52,7 +52,7 @@ pub struct EntityCollisionContext {
pub entity: Entity,
}
pub fn clip(chunk_storage: &mut ChunkStorage, context: ClipContext) -> BlockHitResult {
pub fn clip(chunk_storage: &ChunkStorage, context: ClipContext) -> BlockHitResult {
traverse_blocks(
context.from,
context.to,
@ -108,7 +108,7 @@ fn clip_with_interaction_override(
block_state: &BlockState,
) -> Option<BlockHitResult> {
let block_hit_result = block_shape.clip(from, to, block_pos);
if let Some(mut block_hit_result) = block_hit_result {
if let Some(block_hit_result) = block_hit_result {
// TODO: minecraft calls .getInteractionShape here
// are there even any blocks that have a physics shape different from the
// interaction shape???

View file

@ -54,10 +54,10 @@ fn travel(
),
With<Local>,
>,
world_container: Res<InstanceContainer>,
instance_container: Res<InstanceContainer>,
) {
for (mut physics, direction, mut position, attributes, world_name) in &mut query {
let world_lock = world_container
let world_lock = instance_container
.get(world_name)
.expect("All entities should be in a valid world");
let world = world_lock.read();
@ -176,14 +176,14 @@ pub fn force_jump_listener(
&Sprinting,
&WorldName,
)>,
world_container: Res<InstanceContainer>,
instance_container: Res<InstanceContainer>,
mut events: EventReader<ForceJumpEvent>,
) {
for event in events.iter() {
if let Ok((mut physics, position, direction, sprinting, world_name)) =
query.get_mut(event.0)
{
let world_lock = world_container
let world_lock = instance_container
.get(world_name)
.expect("All entities should be in a valid world");
let world = world_lock.read();

View file

@ -7,13 +7,13 @@ use std::io::{Cursor, Write};
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundUseItemOnPacket {
pub hand: InteractionHand,
pub block_hit: BlockHitResult,
pub block_hit: BlockHit,
#[var]
pub sequence: u32,
}
#[derive(Clone, Debug)]
pub struct BlockHitResult {
pub struct BlockHit {
/// The block that we clicked.
pub block_pos: BlockPos,
/// The face of the block that was clicked.
@ -26,7 +26,7 @@ pub struct BlockHitResult {
pub inside: bool,
}
impl McBufWritable for BlockHitResult {
impl McBufWritable for BlockHit {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
self.block_pos.write_into(buf)?;
self.direction.write_into(buf)?;
@ -47,7 +47,7 @@ impl McBufWritable for BlockHitResult {
}
}
impl McBufReadable for BlockHitResult {
impl McBufReadable for BlockHit {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let block_pos = BlockPos::read_from(buf)?;
let direction = Direction::read_from(buf)?;

View file

@ -8,7 +8,7 @@ use std::{
sync::{Arc, Weak},
};
use crate::{ChunkStorage, Instance};
use crate::{entity::WorldName, ChunkStorage, Instance};
/// A container of [`Instance`]s (aka worlds). Instances are stored as a Weak
/// pointer here, so if no clients are using an instance it will be forgotten.
@ -37,7 +37,7 @@ impl InstanceContainer {
}
/// Get a world from the container.
pub fn get(&self, name: &ResourceLocation) -> Option<Arc<RwLock<Instance>>> {
pub fn get(&self, name: &WorldName) -> Option<Arc<RwLock<Instance>>> {
self.worlds.get(name).and_then(|world| world.upgrade())
}

View file

@ -219,10 +219,10 @@ fn update_entity_chunk_positions(
),
Changed<entity::Position>,
>,
world_container: Res<InstanceContainer>,
instance_container: Res<InstanceContainer>,
) {
for (entity, pos, last_pos, world_name) in query.iter_mut() {
let world_lock = world_container.get(world_name).unwrap();
let world_lock = instance_container.get(world_name).unwrap();
let mut world = world_lock.write();
let old_chunk = ChunkPos::from(*last_pos);
@ -286,11 +286,11 @@ fn debug_detect_updates_received_on_local_entities(
fn remove_despawned_entities_from_indexes(
mut commands: Commands,
mut entity_infos: ResMut<EntityInfos>,
world_container: Res<InstanceContainer>,
instance_container: Res<InstanceContainer>,
query: Query<(Entity, &EntityUuid, &Position, &WorldName, &LoadedBy), Changed<LoadedBy>>,
) {
for (entity, uuid, position, world_name, loaded_by) in &query {
let world_lock = world_container.get(world_name).unwrap();
let world_lock = instance_container.get(world_name).unwrap();
let mut world = world_lock.write();
// if the entity has no references left, despawn it

View file

@ -59,11 +59,11 @@ pub fn deduplicate_entities(
(Changed<MinecraftEntityId>, Without<Local>),
>,
mut loaded_by_query: Query<&mut LoadedBy>,
world_container: Res<InstanceContainer>,
instance_container: Res<InstanceContainer>,
) {
// if this entity already exists, remove it
for (new_entity, id, world_name) in query.iter_mut() {
if let Some(world_lock) = world_container.get(world_name) {
if let Some(world_lock) = instance_container.get(world_name) {
let world = world_lock.write();
if let Some(old_entity) = world.entity_by_id.get(id) {
if old_entity == &new_entity {
@ -104,11 +104,11 @@ pub fn deduplicate_local_entities(
(Entity, &MinecraftEntityId, &WorldName),
(Changed<MinecraftEntityId>, With<Local>),
>,
world_container: Res<InstanceContainer>,
instance_container: Res<InstanceContainer>,
) {
// if this entity already exists, remove the old one
for (new_entity, id, world_name) in query.iter_mut() {
if let Some(world_lock) = world_container.get(world_name) {
if let Some(world_lock) = instance_container.get(world_name) {
let world = world_lock.write();
if let Some(old_entity) = world.entity_by_id.get(id) {
if old_entity == &new_entity {
@ -154,11 +154,11 @@ pub fn update_uuid_index(
// mut commands: Commands,
// partial_entity_infos: &mut PartialEntityInfos,
// chunk: &ChunkPos,
// world_container: &WorldContainer,
// instance_container: &WorldContainer,
// world_name: &WorldName,
// mut query: Query<(&MinecraftEntityId, &mut ReferenceCount)>,
// ) {
// let world_lock = world_container.get(world_name).unwrap();
// let world_lock = instance_container.get(world_name).unwrap();
// let world = world_lock.read();
// if let Some(entities) = world.entities_by_chunk.get(chunk).cloned() {
@ -290,10 +290,10 @@ pub fn update_entity_by_id_index(
(Entity, &MinecraftEntityId, &WorldName, Option<&Local>),
Changed<MinecraftEntityId>,
>,
world_container: Res<InstanceContainer>,
instance_container: Res<InstanceContainer>,
) {
for (entity, id, world_name, local) in query.iter_mut() {
let world_lock = world_container.get(world_name).unwrap();
let world_lock = instance_container.get(world_name).unwrap();
let mut world = world_lock.write();
if local.is_none() {
if let Some(old_entity) = world.entity_by_id.get(id) {

View file

@ -202,7 +202,7 @@ async fn swarm_handle(
SwarmEvent::Chat(m) => {
println!("swarm chat message: {}", m.message().to_ansi());
if m.message().to_string() == "<py5> world" {
for (name, world) in &swarm.world_container.read().worlds {
for (name, world) in &swarm.instance_container.read().worlds {
println!("world name: {name}");
if let Some(w) = world.upgrade() {
for chunk_pos in w.read().chunks.chunks.values() {

View file

@ -93,7 +93,7 @@ fn goto_listener(
mut commands: Commands,
mut events: EventReader<GotoEvent>,
mut query: Query<(&Position, &WorldName)>,
world_container: Res<InstanceContainer>,
instance_container: Res<InstanceContainer>,
) {
let thread_pool = AsyncComputeTaskPool::get();
@ -106,7 +106,7 @@ fn goto_listener(
vertical_vel: VerticalVel::None,
};
let world_lock = world_container
let world_lock = instance_container
.get(world_name)
.expect("Entity tried to pathfind but the entity isn't in a valid world");
let end = event.goal.goal_node();

View file

@ -37,7 +37,7 @@ pub struct Swarm {
// bot_datas: Arc<Mutex<Vec<(Client, S)>>>,
resolved_address: SocketAddr,
address: ServerAddress,
pub world_container: Arc<RwLock<InstanceContainer>>,
pub instance_container: Arc<RwLock<InstanceContainer>>,
bots_tx: mpsc::UnboundedSender<(Option<Event>, Client)>,
swarm_tx: mpsc::UnboundedSender<SwarmEvent>,
@ -248,7 +248,7 @@ where
// resolve the address
let resolved_address = resolver::resolve_address(&address).await?;
let world_container = Arc::new(RwLock::new(InstanceContainer::default()));
let instance_container = Arc::new(RwLock::new(InstanceContainer::default()));
// we can't modify the swarm plugins after this
let (bots_tx, mut bots_rx) = mpsc::unbounded_channel();
@ -263,7 +263,7 @@ where
resolved_address,
address,
world_container,
instance_container,
bots_tx,