1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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);
}
}
}
}
|