1
1
use azalea_block:: { Block , BlockState , FluidState } ;
2
2
use azalea_core:: { direction:: Direction , game_type:: GameMode , position:: BlockPos , tick:: GameTick } ;
3
- use azalea_entity:: { mining:: get_mine_progress, FluidOnEyes , Physics } ;
3
+ use azalea_entity:: { mining:: get_mine_progress, FluidOnEyes , Physics , LocalEntity } ;
4
4
use azalea_inventory:: ItemSlot ;
5
5
use azalea_physics:: PhysicsSet ;
6
6
use azalea_protocol:: packets:: game:: serverbound_player_action_packet:: {
@@ -10,6 +10,7 @@ use azalea_world::{InstanceContainer, InstanceName};
10
10
use bevy_app:: { App , Plugin , Update } ;
11
11
use bevy_ecs:: prelude:: * ;
12
12
use derive_more:: { Deref , DerefMut } ;
13
+ use azalea_entity:: metadata:: Player ;
13
14
14
15
use crate :: {
15
16
interact:: {
@@ -25,6 +26,7 @@ use crate::{
25
26
26
27
/// A plugin that allows clients to break blocks in the world.
27
28
pub struct MinePlugin ;
29
+
28
30
impl Plugin for MinePlugin {
29
31
fn build ( & self , app : & mut App ) {
30
32
app. add_event :: < StartMiningBlockEvent > ( )
@@ -33,7 +35,15 @@ impl Plugin for MinePlugin {
33
35
. add_event :: < StopMiningBlockEvent > ( )
34
36
. add_event :: < MineBlockProgressEvent > ( )
35
37
. add_event :: < AttackBlockEvent > ( )
36
- . add_systems ( GameTick , continue_mining_block. before ( PhysicsSet ) )
38
+ . add_systems (
39
+ GameTick ,
40
+ (
41
+ continue_mining_block,
42
+ handle_left_click_mine
43
+ )
44
+ . chain ( )
45
+ . before ( PhysicsSet ) ,
46
+ )
37
47
. add_systems (
38
48
Update ,
39
49
(
@@ -66,6 +76,69 @@ impl Client {
66
76
position,
67
77
} ) ;
68
78
}
79
+
80
+ /// When enabled, the bot will mine any block that it is looking at if it is reachable.
81
+ pub fn left_click_mine ( & self , enabled : bool ) {
82
+ let mut ecs = self . ecs . lock ( ) ;
83
+ let mut entity_mut = ecs. entity_mut ( self . entity ) ;
84
+
85
+ if enabled {
86
+ entity_mut. insert ( LeftClickMine ) ;
87
+ } else {
88
+ entity_mut. remove :: < LeftClickMine > ( ) ;
89
+ }
90
+ }
91
+ }
92
+
93
+ #[ derive( Component ) ]
94
+ pub struct LeftClickMine ;
95
+
96
+ #[ allow( clippy:: type_complexity) ]
97
+ fn handle_left_click_mine (
98
+ mut query : Query <
99
+ (
100
+ & HitResultComponent ,
101
+ Entity ,
102
+ Option < & Mining > ,
103
+ & InventoryComponent ,
104
+ & MineBlockPos ,
105
+ & MineItem ,
106
+ ) ,
107
+ ( With < LeftClickMine > , With < Player > , With < LocalEntity > ) ,
108
+ > ,
109
+ mut start_mining_block_event : EventWriter < StartMiningBlockEvent > ,
110
+ mut stop_mining_block_event : EventWriter < StopMiningBlockEvent >
111
+ ) {
112
+ for (
113
+ hit_result_component,
114
+ entity,
115
+ mining,
116
+ inventory,
117
+ current_mining_pos,
118
+ current_mining_item,
119
+ ) in & mut query. iter_mut ( )
120
+ {
121
+ let block_pos = hit_result_component. block_pos ;
122
+
123
+ if ( mining. is_none ( )
124
+ || !is_same_mining_target (
125
+ block_pos,
126
+ inventory,
127
+ current_mining_pos,
128
+ current_mining_item,
129
+ ) ) && !hit_result_component. miss
130
+ {
131
+ start_mining_block_event. send ( StartMiningBlockEvent {
132
+ entity,
133
+ position : block_pos,
134
+ } ) ;
135
+ } else if mining. is_some ( ) && hit_result_component. miss {
136
+ // Stop mining as the block is not reachable
137
+ stop_mining_block_event. send ( StopMiningBlockEvent {
138
+ entity
139
+ } ) ;
140
+ }
141
+ }
69
142
}
70
143
71
144
/// Information about the block we're currently mining. This is only present if
@@ -85,6 +158,7 @@ pub struct StartMiningBlockEvent {
85
158
pub entity : Entity ,
86
159
pub position : BlockPos ,
87
160
}
161
+
88
162
fn handle_start_mining_block_event (
89
163
mut events : EventReader < StartMiningBlockEvent > ,
90
164
mut start_mining_events : EventWriter < StartMiningBlockWithDirectionEvent > ,
@@ -113,6 +187,7 @@ pub struct StartMiningBlockWithDirectionEvent {
113
187
pub position : BlockPos ,
114
188
pub direction : Direction ,
115
189
}
190
+
116
191
#[ allow( clippy:: too_many_arguments, clippy:: type_complexity) ]
117
192
fn handle_start_mining_block_with_direction_event (
118
193
mut events : EventReader < StartMiningBlockWithDirectionEvent > ,
@@ -175,11 +250,11 @@ fn handle_start_mining_block_with_direction_event(
175
250
* * mine_delay = 5 ;
176
251
} else if mining. is_none ( )
177
252
|| !is_same_mining_target (
178
- event. position ,
179
- inventory,
180
- & current_mining_pos,
181
- & current_mining_item,
182
- )
253
+ event. position ,
254
+ inventory,
255
+ & current_mining_pos,
256
+ & current_mining_item,
257
+ )
183
258
{
184
259
if mining. is_some ( ) {
185
260
// send a packet to stop mining since we just changed target
@@ -192,7 +267,7 @@ fn handle_start_mining_block_with_direction_event(
192
267
direction : event. direction ,
193
268
sequence : 0 ,
194
269
}
195
- . get ( ) ,
270
+ . get ( ) ,
196
271
} ) ;
197
272
}
198
273
@@ -228,12 +303,12 @@ fn handle_start_mining_block_with_direction_event(
228
303
229
304
if block_is_solid
230
305
&& get_mine_progress (
231
- block. as_ref ( ) ,
232
- held_item. kind ( ) ,
233
- & inventory. inventory_menu ,
234
- fluid_on_eyes,
235
- physics,
236
- ) >= 1.
306
+ block. as_ref ( ) ,
307
+ held_item. kind ( ) ,
308
+ & inventory. inventory_menu ,
309
+ fluid_on_eyes,
310
+ physics,
311
+ ) >= 1.
237
312
{
238
313
// block was broken instantly
239
314
finish_mining_events. send ( FinishMiningBlockEvent {
@@ -264,7 +339,7 @@ fn handle_start_mining_block_with_direction_event(
264
339
direction : event. direction ,
265
340
sequence : * * sequence_number,
266
341
}
267
- . get ( ) ,
342
+ . get ( ) ,
268
343
} ) ;
269
344
}
270
345
}
@@ -414,6 +489,7 @@ fn handle_finish_mining_block_event(
414
489
pub struct StopMiningBlockEvent {
415
490
pub entity : Entity ,
416
491
}
492
+
417
493
fn handle_stop_mining_block_event (
418
494
mut events : EventReader < StopMiningBlockEvent > ,
419
495
mut send_packet_events : EventWriter < SendPacketEvent > ,
@@ -434,7 +510,7 @@ fn handle_stop_mining_block_event(
434
510
direction : Direction :: Down ,
435
511
sequence : 0 ,
436
512
}
437
- . get ( ) ,
513
+ . get ( ) ,
438
514
} ) ;
439
515
commands. entity ( event. entity ) . remove :: < Mining > ( ) ;
440
516
* * mine_progress = 0. ;
@@ -508,7 +584,7 @@ fn continue_mining_block(
508
584
direction : mining. dir ,
509
585
sequence : * * sequence_number,
510
586
}
511
- . get ( ) ,
587
+ . get ( ) ,
512
588
} ) ;
513
589
swing_arm_events. send ( SwingArmEvent { entity } ) ;
514
590
} else if is_same_mining_target (
@@ -554,7 +630,7 @@ fn continue_mining_block(
554
630
direction : mining. dir ,
555
631
sequence : * * sequence_number,
556
632
}
557
- . get ( ) ,
633
+ . get ( ) ,
558
634
} ) ;
559
635
* * mine_progress = 0. ;
560
636
* * mine_ticks = 0. ;
0 commit comments