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