azalea/pathfinder/
debug.rs1use azalea_client::{chat::SendChatEvent, local_player::WorldHolder};
2use azalea_core::position::Vec3;
3use bevy_ecs::prelude::*;
4
5use super::ExecutingPath;
6use crate::pathfinder::moves::should_mine_block_state;
7
8#[derive(Component)]
36pub struct PathfinderDebugParticles;
37
38pub fn debug_render_path_with_particles(
39 mut query: Query<(Entity, &ExecutingPath, &WorldHolder), With<PathfinderDebugParticles>>,
40 chat_events: Option<ResMut<Messages<SendChatEvent>>>,
43 mut tick_count: Local<usize>,
44) {
45 let Some(mut chat_events) = chat_events else {
46 return;
47 };
48 if *tick_count >= 2 {
49 *tick_count = 0;
50 } else {
51 *tick_count += 1;
52 return;
53 }
54 for (entity, executing_path, world_holder) in &mut query {
55 if executing_path.path.is_empty() {
56 continue;
57 }
58
59 let chunks = &world_holder.shared.read().chunks;
60
61 let mut start = executing_path.last_reached_node;
62 for (i, edge) in executing_path.path.iter().enumerate() {
63 let movement = &edge.movement;
64 let end = movement.target;
65
66 let start_vec3 = start.center();
67 let end_vec3 = end.center();
68
69 let step_count = (start_vec3.distance_to(end_vec3) * 4.0) as usize;
70
71 let target_block_state = chunks.get_block_state(movement.target).unwrap_or_default();
72 let above_target_block_state = chunks
73 .get_block_state(movement.target.up(1))
74 .unwrap_or_default();
75 let is_mining = should_mine_block_state(target_block_state)
79 || should_mine_block_state(above_target_block_state);
80
81 let (r, g, b): (f64, f64, f64) = if i == 0 {
82 (0., 1., 0.)
83 } else if is_mining {
84 (1., 0., 0.)
85 } else {
86 (0., 1., 1.)
87 };
88
89 for i in 0..step_count {
91 let percent = i as f64 / step_count as f64;
92 let pos = Vec3 {
93 x: start_vec3.x + (end_vec3.x - start_vec3.x) * percent,
94 y: start_vec3.y + (end_vec3.y - start_vec3.y) * percent,
95 z: start_vec3.z + (end_vec3.z - start_vec3.z) * percent,
96 };
97 let particle_command = format!(
98 "/particle dust{{color:[{r},{g},{b}],scale:{size}}} {start_x} {start_y} {start_z} {delta_x} {delta_y} {delta_z} 0 {count}",
99 size = 1,
100 start_x = pos.x,
101 start_y = pos.y,
102 start_z = pos.z,
103 delta_x = 0,
104 delta_y = 0,
105 delta_z = 0,
106 count = 1
107 );
108 chat_events.write(SendChatEvent {
109 entity,
110 content: particle_command,
111 });
112 }
113
114 start = movement.target;
115 }
116 }
117}