@@ -30,6 +30,12 @@ pub struct DungeonPlayer {
3030 // however if you pair with cooldowns it should be fine
3131 pub active_abilities : Cell < Vec < ActiveAbility > > ,
3232 pub cooldowns : HashMap < DungeonItem , Cooldown > ,
33+
34+ #[ cfg( feature = "dungeon_breaker" ) ]
35+ pub pickaxe_charges : usize ,
36+ #[ cfg( feature = "dungeon_breaker" ) ]
37+ pub broken_blocks : Vec < ( IVec3 , Blocks , usize ) > ,
38+
3339}
3440
3541impl PlayerExtension for DungeonPlayer {
@@ -70,29 +76,101 @@ impl PlayerExtension for DungeonPlayer {
7076 cooldown. ticks_remaining -= 1 ;
7177 cooldown. ticks_remaining != 0
7278 } ) ;
79+
80+ #[ cfg( feature = "dungeon_breaker" ) ]
81+ {
82+ if player. ticks_existed . is_multiple_of ( 20 ) {
83+ if player. extension . pickaxe_charges != 20 {
84+ let min = min ( 20 - player. extension . pickaxe_charges , 2 ) ;
85+ player. extension . pickaxe_charges += min;
86+ }
87+ }
88+
89+ let chunk_grid = & mut player. world_mut ( ) . chunk_grid ;
90+ player. extension . broken_blocks . retain_mut ( |( position, block, ticks) | {
91+ * ticks -= 1 ;
92+ if * ticks == 0 {
93+ // for last 3 seconds, every second plays a particle and sound
94+ chunk_grid. set_block_at ( * block, position. x , position. y , position. z ) ;
95+ }
96+ * ticks != 0
97+ } ) ;
98+ }
7399 }
74100
75101 fn dig ( player : & mut Player < Self > , position : IVec3 , action : & PlayerDiggingAction ) {
76- let mut restore_block = false ;
77- match action {
78- PlayerDiggingAction :: StartDestroyBlock => {
79- if let Some ( item) = * player. inventory . get_hotbar_slot ( player. held_slot as usize ) {
80- if matches ! ( item, DungeonItem :: Pickaxe ) {
81- restore_block = true ;
102+
103+ #[ cfg( not( feature = "dungeon_breaker" ) ) ]
104+ {
105+ let mut restore_block = false ;
106+ match action {
107+ PlayerDiggingAction :: StartDestroyBlock => {
108+ if let Some ( item) = * player. inventory . get_hotbar_slot ( player. held_slot as usize ) {
109+ if matches ! ( item, DungeonItem :: Pickaxe ) {
110+ restore_block = true ;
111+ }
82112 }
113+
114+ // only doors can be interacted with left click I think
115+ let world = player. world_mut ( ) ;
116+ DungeonPlayer :: try_open_door ( player, world, & position) ;
83117 }
84-
85- // only doors can be interacted with left click I think
86- let world = player . world_mut ( ) ;
87- DungeonPlayer :: try_open_door ( player , world , & position ) ;
118+ PlayerDiggingAction :: FinishDestroyBlock => {
119+ restore_block = true ;
120+ }
121+ _ => { }
88122 }
89- PlayerDiggingAction :: FinishDestroyBlock => {
90- restore_block = true ;
123+ if restore_block {
124+ let block = player. world ( ) . chunk_grid . get_block_at ( position. x , position. y , position. z ) ;
125+ player. write_packet ( & BlockChange {
126+ block_pos : position,
127+ block_state : block. get_block_state_id ( ) ,
128+ } )
91129 }
92- _ => { }
93130 }
94- if restore_block {
95- let block = player. world ( ) . chunk_grid . get_block_at ( position. x , position. y , position. z ) ;
131+
132+ #[ cfg( feature = "dungeon_breaker" ) ]
133+ {
134+ let world = & mut player. world_mut ( ) ;
135+
136+ let can_break = world. has_started ( ) && player. extension . pickaxe_charges != 0 ;
137+ if matches ! ( action, PlayerDiggingAction :: StartDestroyBlock ) && can_break {
138+
139+ let opened_door = DungeonPlayer :: try_open_door ( player, world, & position) ;
140+ let held_slot = player. inventory . get_hotbar_slot ( player. held_slot as usize ) ;
141+
142+ if !opened_door && matches ! ( held_slot, Some ( DungeonItem :: Pickaxe ) ) {
143+ let chunk_grid = & mut world. chunk_grid ;
144+
145+ let block_aabb = AABB :: new (
146+ position. as_dvec3 ( ) + dvec3 ( -0.75 , -0.75 , -0.75 ) ,
147+ position. as_dvec3 ( ) + dvec3 ( 1.5 , 1.5 , 1.5 ) ,
148+ ) ;
149+
150+ if let Some ( ( room_rc, _) ) = & player. extension . current_room {
151+ let room = room_rc. borrow ( ) ;
152+
153+ // check if room doesn't allow, check if overlaps with secrets
154+
155+ let mut volume_inside = 0.0 ;
156+
157+ for bounds in room. room_bounds . iter ( ) {
158+ volume_inside += block_aabb. intersection_volume ( & bounds. aabb ) ;
159+ }
160+ // if volume doesn't match, that means the block is likely on the border
161+ if block_aabb. volume ( ) == volume_inside {
162+ let previous = chunk_grid. get_block_at ( position. x , position. y , position. z ) ;
163+ player. extension . broken_blocks . push ( ( position, previous, 200 ) ) ;
164+
165+ chunk_grid. set_block_at ( Blocks :: Air , position. x , position. y , position. z ) ;
166+ player. extension . pickaxe_charges -= 1 ;
167+ return ;
168+ }
169+ }
170+ }
171+ }
172+
173+ let block = world. chunk_grid . get_block_at ( position. x , position. y , position. z ) ;
96174 player. write_packet ( & BlockChange {
97175 block_pos : position,
98176 block_state : block. get_block_state_id ( ) ,
@@ -164,7 +242,7 @@ impl DungeonPlayer {
164242 None
165243 }
166244
167- pub fn try_open_door ( player : & mut Player < Self > , world : & mut World < Dungeon > , position : & IVec3 ) {
245+ pub fn try_open_door ( player : & mut Player < Self > , world : & mut World < Dungeon > , position : & IVec3 ) -> bool {
168246 if world. has_started ( ) {
169247 if let Some ( room_rc) = player. extension . get_current_room ( ) {
170248 for neighbour in room_rc. borrow ( ) . neighbours ( ) {
@@ -185,10 +263,12 @@ impl DungeonPlayer {
185263 door. open ( world) ;
186264 }
187265 neighbour. room . borrow_mut ( ) . discovered = true ;
188- world. map . draw_room ( & neighbour. room . borrow ( ) )
266+ world. map . draw_room ( & neighbour. room . borrow ( ) ) ;
267+ return true ;
189268 }
190269 }
191270 }
271+ false
192272 }
193273
194274 fn update_sidebar ( player : & mut Player < DungeonPlayer > ) {
@@ -267,12 +347,22 @@ impl DungeonPlayer {
267347 Keys: §c■ {has_blood_key} §8■ §a{wither_key_count}x
268348 Time elapsed: §a§a{time}
269349 Cleared: §c{clear_percent}% §8§8({score})
270-
350+
271351 "# ,
272352 clear_percent = "0" ,
273353 score = "0" ,
274354 } ) ;
275355
356+ // if cfg!(feature = "dungeon_breaker") {
357+ #[ cfg( feature = "dungeon_breaker" ) ]
358+ sidebar. push ( & format ! { r#"
359+ charges {charges}
360+
361+ "# ,
362+ charges = player. extension. pickaxe_charges,
363+ } ) ;
364+ // }
365+
276366 if world. players . len ( ) == 1 {
277367 sidebar. push ( indoc ! { r#"
278368 §3§lSolo
0 commit comments