@@ -9,6 +9,7 @@ use ferrumc_macros::{NBTDeserialize, NBTSerialize};
9
9
use ferrumc_net_codec:: net_types:: var_int:: VarInt ;
10
10
use lazy_static:: lazy_static;
11
11
use std:: cmp:: max;
12
+ use std:: collections:: hash_map:: Entry ;
12
13
use std:: collections:: HashMap ;
13
14
use std:: io:: Read ;
14
15
use tracing:: { debug, error, warn} ;
@@ -40,7 +41,7 @@ lazy_static! {
40
41
ID2BLOCK . iter( ) . map( |( k, v) | ( v. clone( ) , * k) ) . collect( ) ;
41
42
}
42
43
43
- #[ derive( Encode , Decode , Clone , DeepSizeOf ) ]
44
+ #[ derive( Encode , Decode , Clone , DeepSizeOf , Eq , PartialEq ) ]
44
45
// This is a placeholder for the actual chunk format
45
46
pub struct Chunk {
46
47
pub x : i32 ,
@@ -52,28 +53,29 @@ pub struct Chunk {
52
53
53
54
#[ derive( Encode , Decode , NBTDeserialize , NBTSerialize , Clone , DeepSizeOf ) ]
54
55
#[ nbt( net_encode) ]
56
+ #[ derive( Eq , PartialEq ) ]
55
57
pub struct Heightmaps {
56
58
#[ nbt( rename = "MOTION_BLOCKING" ) ]
57
59
pub motion_blocking : Vec < i64 > ,
58
60
#[ nbt( rename = "WORLD_SURFACE" ) ]
59
61
pub world_surface : Vec < i64 > ,
60
62
}
61
- #[ derive( Encode , Decode , Clone , DeepSizeOf ) ]
63
+ #[ derive( Encode , Decode , Clone , DeepSizeOf , Eq , PartialEq ) ]
62
64
pub struct Section {
63
65
pub y : i8 ,
64
66
pub block_states : BlockStates ,
65
67
pub biome_states : BiomeStates ,
66
68
pub block_light : Vec < u8 > ,
67
69
pub sky_light : Vec < u8 > ,
68
70
}
69
- #[ derive( Encode , Decode , Clone , DeepSizeOf ) ]
71
+ #[ derive( Encode , Decode , Clone , DeepSizeOf , Eq , PartialEq ) ]
70
72
pub struct BlockStates {
71
73
pub non_air_blocks : u16 ,
72
74
pub block_data : PaletteType ,
73
75
pub block_counts : HashMap < BlockData , i32 > ,
74
76
}
75
77
76
- #[ derive( Encode , Decode , Clone , DeepSizeOf ) ]
78
+ #[ derive( Encode , Decode , Clone , DeepSizeOf , Eq , PartialEq ) ]
77
79
pub enum PaletteType {
78
80
Single ( VarInt ) ,
79
81
Indirect {
@@ -87,7 +89,7 @@ pub enum PaletteType {
87
89
} ,
88
90
}
89
91
90
- #[ derive( Encode , Decode , Clone , DeepSizeOf ) ]
92
+ #[ derive( Encode , Decode , Clone , DeepSizeOf , Eq , PartialEq ) ]
91
93
pub struct BiomeStates {
92
94
pub bits_per_biome : u8 ,
93
95
pub data : Vec < i64 > ,
@@ -127,7 +129,7 @@ impl VanillaChunk {
127
129
let mut sections = Vec :: new ( ) ;
128
130
for section in self . sections . as_ref ( ) . unwrap ( ) {
129
131
let y = section. y ;
130
- let mut block_data: PaletteType ;
132
+ let block_data: PaletteType ;
131
133
let raw_block_data = section
132
134
. block_states
133
135
. as_ref ( )
@@ -277,7 +279,7 @@ impl BlockStates {
277
279
278
280
// Extract value at the current bit offset
279
281
let value =
280
- read_nbit_i32 ( & long, * bits_per_block as usize , bit_offset as u32 ) ?;
282
+ read_nbit_i32 ( long, * bits_per_block as usize , bit_offset as u32 ) ?;
281
283
let max_int_value = ( 1 << new_bit_size) - 1 ;
282
284
if value > max_int_value {
283
285
return Err ( InvalidBlockStateData ( format ! (
@@ -391,6 +393,7 @@ impl Chunk {
391
393
. iter_mut ( )
392
394
. find ( |section| section. y == ( y >> 4 ) as i8 )
393
395
. ok_or ( WorldError :: SectionOutOfBounds ( y >> 4 ) ) ?;
396
+ // Do different things based on the palette type
394
397
match & mut section. block_states . block_data {
395
398
PaletteType :: Single ( val) => {
396
399
debug ! ( "Converting single block to indirect palette" ) ;
@@ -408,15 +411,17 @@ impl Chunk {
408
411
palette,
409
412
} => {
410
413
let block_counts = & mut section. block_states . block_counts ;
411
- match block_counts. get_mut ( & old_block) {
412
- Some ( e) => {
413
- if * e <= 0 {
414
+ match block_counts. entry ( old_block. clone ( ) ) {
415
+ Entry :: Occupied ( mut occ_entry) => {
416
+ let count = occ_entry. get_mut ( ) ;
417
+ if * count <= 0 {
414
418
return Err ( WorldError :: InvalidBlock ( old_block) ) ;
415
419
}
416
- * e -= 1 ;
420
+ * count -= 1 ;
417
421
}
418
- None => {
422
+ Entry :: Vacant ( empty_entry ) => {
419
423
warn ! ( "Block not found in block counts: {:?}" , old_block) ;
424
+ empty_entry. insert ( 0 ) ;
420
425
}
421
426
}
422
427
let block_id = BLOCK2ID
@@ -536,12 +541,16 @@ impl Chunk {
536
541
}
537
542
538
543
pub fn new ( x : i32 , z : i32 , dimension : String ) -> Self {
539
- let mut sections: Vec < Section > = ( 0 ..24 )
544
+ let sections: Vec < Section > = ( 0 ..24 )
540
545
. map ( |y| Section {
541
546
y : y as i8 ,
542
547
block_states : BlockStates {
543
548
non_air_blocks : 0 ,
544
- block_data : PaletteType :: Single ( VarInt :: from ( 0 ) ) ,
549
+ block_data : PaletteType :: Indirect {
550
+ bits_per_block : 4 ,
551
+ data : vec ! [ 0 ; 256 ] ,
552
+ palette : vec ! [ VarInt :: from( 0 ) ] ,
553
+ } ,
545
554
block_counts : HashMap :: from ( [ ( BlockData :: default ( ) , 4096 ) ] ) ,
546
555
} ,
547
556
biome_states : BiomeStates {
@@ -579,7 +588,7 @@ impl Chunk {
579
588
/// * `Err(WorldError)` - If an error occurs while setting the section.
580
589
pub fn set_section ( & mut self , section : u8 , block : BlockData ) -> Result < ( ) , WorldError > {
581
590
if let Some ( section) = self . sections . get_mut ( section as usize ) {
582
- section. fill ( block)
591
+ section. fill ( block. clone ( ) )
583
592
} else {
584
593
Err ( WorldError :: SectionOutOfBounds ( section as i32 ) )
585
594
}
0 commit comments