aboutsummaryrefslogtreecommitdiff
path: root/azalea-client/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'azalea-client/src/plugins')
-rw-r--r--azalea-client/src/plugins/inventory.rs50
-rw-r--r--azalea-client/src/plugins/mining.rs87
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 {