aboutsummaryrefslogtreecommitdiff
path: root/azalea-client/src/plugins/block_update.rs
diff options
context:
space:
mode:
Diffstat (limited to 'azalea-client/src/plugins/block_update.rs')
-rw-r--r--azalea-client/src/plugins/block_update.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/azalea-client/src/plugins/block_update.rs b/azalea-client/src/plugins/block_update.rs
new file mode 100644
index 00000000..15e885b6
--- /dev/null
+++ b/azalea-client/src/plugins/block_update.rs
@@ -0,0 +1,49 @@
+use azalea_block::BlockState;
+use azalea_core::position::BlockPos;
+use bevy_app::{App, Plugin, Update};
+use bevy_ecs::prelude::*;
+
+use crate::{
+ chunks::handle_receive_chunk_event, interact::BlockStatePredictionHandler,
+ local_player::InstanceHolder,
+};
+
+pub struct BlockUpdatePlugin;
+impl Plugin for BlockUpdatePlugin {
+ fn build(&self, app: &mut App) {
+ app.add_systems(
+ Update,
+ // has to be after ReceiveChunkEvent is handled so if we get chunk+blockupdate in one
+ // Update then the block update actually gets applied
+ handle_block_update_event.after(handle_receive_chunk_event),
+ );
+ }
+}
+
+/// A component that holds the list of block updates that need to be handled.
+///
+/// This is updated by `read_packets` (in `PreUpdate`) and handled/cleared by
+/// [`handle_block_update_event`] (`Update`).
+///
+/// This is a component instead of an ECS event for performance reasons.
+#[derive(Component, Debug, Clone, Default)]
+pub struct QueuedServerBlockUpdates {
+ pub list: Vec<(BlockPos, BlockState)>,
+}
+
+pub fn handle_block_update_event(
+ mut query: Query<(
+ &mut QueuedServerBlockUpdates,
+ &InstanceHolder,
+ &mut BlockStatePredictionHandler,
+ )>,
+) {
+ for (mut queued, instance_holder, mut prediction_handler) in query.iter_mut() {
+ let world = instance_holder.instance.read();
+ for (pos, block_state) in queued.list.drain(..) {
+ if !prediction_handler.update_known_server_state(pos, block_state) {
+ world.chunks.set_block_state(pos, block_state);
+ }
+ }
+ }
+}