diff options
Diffstat (limited to 'azalea-client/src/plugins')
| -rw-r--r-- | azalea-client/src/plugins/inventory.rs | 50 | ||||
| -rw-r--r-- | azalea-client/src/plugins/mining.rs | 87 |
2 files changed, 84 insertions, 53 deletions
diff --git a/azalea-client/src/plugins/inventory.rs b/azalea-client/src/plugins/inventory.rs index 3c57b3cc..a805ae9b 100644 --- a/azalea-client/src/plugins/inventory.rs +++ b/azalea-client/src/plugins/inventory.rs @@ -18,32 +18,28 @@ use azalea_protocol::packets::game::{ }; use azalea_registry::MenuKind; use azalea_world::{InstanceContainer, InstanceName}; -use bevy_app::{App, Plugin, Update}; +use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; use indexmap::IndexMap; use tracing::{error, warn}; -use crate::{Client, packet::game::SendGamePacketEvent, respawn::perform_respawn}; +use crate::{Client, packet::game::SendGamePacketEvent}; pub struct InventoryPlugin; impl Plugin for InventoryPlugin { fn build(&self, app: &mut App) { - app.add_message::<SetSelectedHotbarSlotEvent>() - .add_systems( - Update, - handle_set_selected_hotbar_slot_event - .in_set(InventorySystems) - .before(perform_respawn), - ) - .add_systems( - GameTick, - ensure_has_sent_carried_item.after(super::mining::handle_mining_queued), - ) - .add_observer(handle_client_side_close_container_trigger) - .add_observer(handle_menu_opened_trigger) - .add_observer(handle_container_close_event) - .add_observer(handle_set_container_content_trigger) - .add_observer(handle_container_click_event); + app.add_systems( + GameTick, + ensure_has_sent_carried_item.after(super::mining::handle_mining_queued), + ) + .add_observer(handle_client_side_close_container_trigger) + .add_observer(handle_menu_opened_trigger) + .add_observer(handle_container_close_event) + .add_observer(handle_set_container_content_trigger) + .add_observer(handle_container_click_event) + // number keys are checked on tick but scrolling can happen outside of ticks, therefore + // this is fine + .add_observer(handle_set_selected_hotbar_slot_event); } } @@ -83,7 +79,7 @@ impl Client { ); let mut ecs = self.ecs.lock(); - ecs.write_message(SetSelectedHotbarSlotEvent { + ecs.trigger(SetSelectedHotbarSlotEvent { entity: self.entity, slot: new_hotbar_slot_index, }); @@ -926,26 +922,18 @@ pub fn handle_set_container_content_trigger( /// An ECS message to switch our hand to a different hotbar slot. /// /// This is equivalent to using the scroll wheel or number keys in Minecraft. -#[derive(Message)] +#[derive(EntityEvent)] pub struct SetSelectedHotbarSlotEvent { pub entity: Entity, /// The hotbar slot to select. This should be in the range 0..=8. pub slot: u8, } pub fn handle_set_selected_hotbar_slot_event( - mut events: MessageReader<SetSelectedHotbarSlotEvent>, + set_selected_hotbar_slot: On<SetSelectedHotbarSlotEvent>, mut query: Query<&mut Inventory>, ) { - for event in events.read() { - let mut inventory = query.get_mut(event.entity).unwrap(); - - // if the slot is already selected, don't send a packet - if inventory.selected_hotbar_slot == event.slot { - continue; - } - - inventory.selected_hotbar_slot = event.slot; - } + let mut inventory = query.get_mut(set_selected_hotbar_slot.entity).unwrap(); + inventory.selected_hotbar_slot = set_selected_hotbar_slot.slot; } /// The item slot that the server thinks we have selected. diff --git a/azalea-client/src/plugins/mining.rs b/azalea-client/src/plugins/mining.rs index 5fd0aa4a..fda54521 100644 --- a/azalea-client/src/plugins/mining.rs +++ b/azalea-client/src/plugins/mining.rs @@ -8,7 +8,7 @@ use azalea_world::{InstanceContainer, InstanceName}; use bevy_app::{App, Plugin, Update}; use bevy_ecs::prelude::*; use derive_more::{Deref, DerefMut}; -use tracing::{debug, trace}; +use tracing::{debug, trace, warn}; use crate::{ Client, @@ -73,6 +73,7 @@ impl Client { ecs.write_message(StartMiningBlockEvent { entity: self.entity, position, + force: true, }); } @@ -138,6 +139,7 @@ fn handle_auto_mine( start_mining_block_event.write(StartMiningBlockEvent { entity, position: block_pos, + force: true, }); } else if mining.is_some() && hit_result_component.miss() { stop_mining_block_event.write(StopMiningBlockEvent { entity }); @@ -163,6 +165,14 @@ pub struct Mining { pub struct StartMiningBlockEvent { pub entity: Entity, pub position: BlockPos, + /// Whether we should ignore blocks that are blocking the view of this + /// block. + /// + /// Most of the time, you'll want to set this to true as it'll make the + /// behavior more predictable. If it's set to false, then it might fail or + /// it might mine blocks other than the one at `position` (which may be + /// preferable if you're trying to act like vanilla). + pub force: bool, } fn handle_start_mining_block_event( mut commands: Commands, @@ -172,25 +182,44 @@ fn handle_start_mining_block_event( for event in events.read() { trace!("{event:?}"); let hit_result = query.get_mut(event.entity).unwrap(); - let (direction, force) = if let Some(block_hit_result) = - hit_result.as_block_hit_result_if_not_miss() - && block_hit_result.block_pos == event.position - { - // we're looking at the block - (block_hit_result.direction, false) + if event.force { + let direction = if let Some(block_hit_result) = + hit_result.as_block_hit_result_if_not_miss() + && block_hit_result.block_pos == event.position + { + // we're looking at the block + block_hit_result.direction + } else { + debug!( + "Got StartMiningBlockEvent but we're not looking at the block ({hit_result:?}.block_pos != {:?}). Picking an arbitrary direction instead.", + event.position + ); + // we're not looking at the block, arbitrary direction + Direction::Down + }; + commands.entity(event.entity).insert(MiningQueued { + position: event.position, + direction, + force: true, + }); } else { - debug!( - "Got StartMiningBlockEvent but we're not looking at the block ({:?}.block_pos != {:?}). Picking an arbitrary direction instead.", - hit_result, event.position - ); - // we're not looking at the block, arbitrary direction - (Direction::Down, true) - }; - commands.entity(event.entity).insert(MiningQueued { - position: event.position, - direction, - force, - }); + // let block_hit_result = hit_result.as_block_hit_result_if_not_miss(); + // let direction = block_hit_result.map_or(Direction::Down, |b| b.direction); + if let Some(block_hit_result) = hit_result.as_block_hit_result_if_not_miss() + && block_hit_result.block_pos == event.position + { + commands.entity(event.entity).insert(MiningQueued { + position: event.position, + direction: block_hit_result.direction, + force: false, + }); + } else { + warn!( + "Got StartMiningBlockEvent with force=false but we're not looking at the block ({hit_result:?}.block_pos != {:?}). You should've looked at the block before trying to mine with force=false.", + event.position + ); + }; + } } } @@ -215,7 +244,7 @@ pub fn handle_mining_queued( &Inventory, &FluidOnEyes, &Physics, - Option<&Mining>, + Option<&mut Mining>, &mut BlockStatePredictionHandler, &mut MineDelay, &mut MineProgress, @@ -232,7 +261,7 @@ pub fn handle_mining_queued( inventory, fluid_on_eyes, physics, - mining, + mut mining, mut sequence_number, mut mine_delay, mut mine_progress, @@ -241,6 +270,7 @@ pub fn handle_mining_queued( mut current_mining_pos, ) in query { + trace!("handle_mining_queued {mining_queued:?}"); commands.entity(entity).remove::<MiningQueued>(); let instance = instance_holder.instance.read(); @@ -255,6 +285,13 @@ pub fn handle_mining_queued( // TODO (when world border is implemented): vanilla ignores if the block // is outside of the worldborder + if let Some(mining) = &mut mining { + // this matters if we were previously mining a block without force + if mining_queued.force { + mining.force = true; + } + } + if game_mode.current == GameMode::Creative { // In creative mode, first send START_DESTROY_BLOCK packet then immediately // finish mining @@ -686,7 +723,13 @@ pub fn update_mining_component( continue; } - mining.pos = block_hit_result.block_pos; + if mining.pos != block_hit_result.block_pos { + debug!( + "Updating Mining::pos from {:?} to {:?}", + mining.pos, block_hit_result.block_pos + ); + mining.pos = block_hit_result.block_pos; + } mining.dir = block_hit_result.direction; } else { if mining.force { |
