1
+ use std:: mem;
2
+
1
3
use base:: { BlockKind , ItemStack , ValidBlockPosition } ;
2
4
use ecs:: { EntityBuilder , SysResult , SystemExecutor } ;
3
5
use libcraft_items:: EnchantmentKind ;
@@ -14,6 +16,7 @@ pub enum BlockBreaker {
14
16
Inactive ,
15
17
}
16
18
impl BlockBreaker {
19
+ /// Create a new active instance pointing to `block_pos`. Calculates the time needed using `world.block_at(block_pos)` and `equipped_item`.
17
20
pub fn new (
18
21
world : & mut World ,
19
22
block_pos : ValidBlockPosition ,
@@ -23,59 +26,69 @@ impl BlockBreaker {
23
26
. map ( Self :: Active )
24
27
. unwrap_or ( Self :: Inactive )
25
28
}
29
+ /// If active, produces a `DestroyStateChange` event for the adequate position.
26
30
pub fn destroy_change_event ( & self ) -> Option < DestroyStateChange > {
27
31
Some ( DestroyStateChange ( self . position ( ) ?, self . destroy_stage ( ) ) )
28
32
}
33
+ /// If active or finished, returns the pointed to position.
29
34
pub fn position ( & self ) -> Option < ValidBlockPosition > {
30
35
match self {
31
36
BlockBreaker :: Active ( a) => Some ( a. position ) ,
32
37
BlockBreaker :: Finished ( f) => Some ( f. position ) ,
33
38
BlockBreaker :: Inactive => None ,
34
39
}
35
40
}
41
+ /// If active, returns the underlying `ActiveBreaker`.
36
42
pub fn active ( & self ) -> Option < & ActiveBreaker > {
37
43
match self {
38
44
Self :: Active ( a) => Some ( a) ,
39
45
_ => None ,
40
46
}
41
47
}
48
+ /// If finished, returns the underlying `FinishedBreaker`.
42
49
pub fn finished ( & self ) -> Option < & FinishedBreaker > {
43
50
match self {
44
51
Self :: Finished ( f) => Some ( f) ,
45
52
_ => None ,
46
53
}
47
54
}
55
+ /// Progresses block breaking. Returns a (newly_finished, do_destry_state_change) tuple.
56
+ /// If this operation finishes block breaking, this turns `self` into `Self::Finished` with the same position.
48
57
pub fn tick ( & mut self ) -> ( bool , bool ) {
49
58
let ( block_break, stage_update) = if let Self :: Active ( breaker) = self {
50
59
breaker. tick ( )
51
60
} else {
52
61
( false , false )
53
62
} ;
54
63
if block_break {
55
- let fin = match self {
56
- Self :: Active ( a) => a. clone ( ) . finish ( ) ,
64
+ let fin = match mem :: take ( self ) {
65
+ Self :: Active ( a) => a. finish ( ) ,
57
66
_ => unreachable ! ( ) ,
58
67
} ;
59
68
* self = Self :: Finished ( fin) ;
60
69
}
61
70
( block_break, stage_update)
62
71
}
72
+ /// Returns the block destroying progress in a range of 0 - 9. When inactive or finished, returns 10.
63
73
pub fn destroy_stage ( & self ) -> u8 {
64
74
match self {
65
75
BlockBreaker :: Active ( a) => a. destroy_stage ( ) ,
66
76
_ => 10 ,
67
77
}
68
78
}
79
+ /// Set `self` to `Self::Inactive`.
69
80
pub fn cancel ( & mut self ) {
70
81
* self = Self :: Inactive ;
71
82
}
83
+ /// Check if the breaker points to `pos`. Returns `true` when `self` is `Self::Inactive`.
72
84
pub fn matches_position ( & self , pos : ValidBlockPosition ) -> bool {
73
85
match self {
74
86
BlockBreaker :: Active ( a) => a. position == pos,
75
87
BlockBreaker :: Finished ( f) => f. position == pos,
76
88
BlockBreaker :: Inactive => true ,
77
89
}
78
90
}
91
+ /// Attempts to finish breaking the target block, optionally turning `self` into `Self::Finished`.
79
92
pub fn try_finish ( & mut self ) -> Option < FinishedBreaker > {
80
93
let this = self . clone ( ) ;
81
94
match this {
@@ -93,13 +106,19 @@ impl BlockBreaker {
93
106
}
94
107
}
95
108
}
109
+ impl Default for BlockBreaker {
110
+ fn default ( ) -> Self {
111
+ Self :: Inactive
112
+ }
113
+ }
96
114
#[ derive( Clone ) ]
97
115
pub struct FinishedBreaker {
98
116
pub position : ValidBlockPosition ,
99
117
pub drop_item : bool ,
100
118
pub fake_finished : bool ,
101
119
}
102
120
impl FinishedBreaker {
121
+ /// Breaks the targeted block and spawns its drops. TODO: make drops work.
103
122
pub fn break_block ( & self , game : & mut Game ) -> SysResult {
104
123
let target_block = match game. block ( self . position ) {
105
124
Some ( b) => b,
0 commit comments