fastanvil/complete/
section_tower.rs1use std::ops::Range;
2
3use crate::biome::Biome;
4use crate::complete::section::{Section, SectionBlockIter};
5use crate::pre13::Pre13Section;
6use crate::pre18::Pre18Section;
7use crate::{java, Block};
8
9pub struct SectionTower {
10 sections: Vec<Section>,
11
12 y_min: isize,
13 y_max: isize,
14}
15
16impl SectionTower {
17 pub fn block(&self, x: usize, y: isize, z: usize) -> Option<&Block> {
18 let section_index = self.y_to_index(y);
19
20 let section = self.sections.get(section_index).unwrap();
21
22 let section_y = y - ((16 * section_index) as isize + self.y_min);
24
25 section.block(x, section_y as usize, z)
26 }
27
28 pub fn biome(&self, x: usize, y: isize, z: usize) -> Option<Biome> {
29 let section_index = self.y_to_index(y);
30
31 let section = self.sections.get(section_index).unwrap();
32
33 let section_y = y - ((16 * section_index) as isize + self.y_min);
35
36 section.biome(x, section_y as usize, z)
37 }
38
39 fn y_to_index(&self, y: isize) -> usize {
40 ((y - self.y_min) / 16) as usize
41 }
42
43 pub fn y_range(&self) -> Range<isize> {
44 self.y_min..self.y_max
45 }
46
47 pub fn iter_blocks(&self) -> SectionTowerBlockIter {
48 SectionTowerBlockIter::new(self)
49 }
50}
51
52impl From<java::SectionTower<java::Section>> for SectionTower {
53 fn from(current_tower: java::SectionTower<java::Section>) -> Self {
54 let mut tower = SectionTower {
55 sections: vec![],
56 y_min: current_tower.y_min(),
57 y_max: current_tower.y_max(),
58 };
59
60 for section in current_tower.take_sections() {
64 tower.sections.push(section.into())
65 }
66
67 tower
68 }
69}
70
71impl From<(java::SectionTower<Pre18Section>, Vec<Biome>)> for SectionTower {
72 fn from(
73 (current_tower, current_biomes): (java::SectionTower<Pre18Section>, Vec<Biome>),
74 ) -> Self {
75 let mut tower = SectionTower {
76 sections: vec![],
77 y_min: current_tower.y_min(),
78 y_max: current_tower.y_max(),
79 };
80
81 const BIOME_COUNT: usize = 4 * 4 * 4;
82
83 for (index, section) in current_tower
86 .take_sections()
87 .into_iter()
88 .enumerate()
89 .skip(1)
90 {
91 tower.sections.push(
92 (
93 section,
94 ¤t_biomes[((index - 1) * BIOME_COUNT)..(index * BIOME_COUNT)],
95 )
96 .into(),
97 );
98 }
99
100 tower
101 }
102}
103
104impl From<(java::SectionTower<Pre13Section>, Vec<Block>, Vec<Biome>)> for SectionTower {
105 fn from(
106 (current_tower, current_blocks, current_biomes): (
107 java::SectionTower<Pre13Section>,
108 Vec<Block>,
109 Vec<Biome>,
110 ),
111 ) -> Self {
112 let mut tower = SectionTower {
113 sections: vec![],
114 y_min: current_tower.y_min(),
115 y_max: current_tower.y_max(),
116 };
117
118 const BIOME_COUNT: usize = 4 * 4 * 4;
119 const BLOCK_COUNT: usize = 16 * 16 * 16;
120
121 for (index, _section) in current_tower.take_sections().into_iter().enumerate() {
122 tower.sections.push(
123 (
124 ¤t_blocks[(index * BLOCK_COUNT)..((index + 1) * BLOCK_COUNT)],
125 ¤t_biomes[(index * BIOME_COUNT)..((index + 1) * BIOME_COUNT)],
126 )
127 .into(),
128 );
129 }
130
131 tower
132 }
133}
134
135pub struct SectionTowerBlockIter<'a> {
136 sections: &'a Vec<Section>,
137
138 section_index_current: usize,
139 section_iter_current: SectionBlockIter<'a>,
140}
141
142impl<'a> SectionTowerBlockIter<'a> {
143 pub fn new(section_tower: &'a SectionTower) -> Self {
144 Self {
145 sections: §ion_tower.sections,
146 section_iter_current: section_tower.sections.get(0).unwrap().iter_blocks(),
147 section_index_current: 0,
148 }
149 }
150}
151
152impl<'a> Iterator for SectionTowerBlockIter<'a> {
153 type Item = &'a Block;
154
155 fn next(&mut self) -> Option<Self::Item> {
156 return match self.section_iter_current.next() {
157 None => {
158 if self.section_index_current >= self.sections.len() - 1 {
160 return None;
161 }
162
163 self.section_index_current += 1;
164 self.section_iter_current = self
165 .sections
166 .get(self.section_index_current)
167 .unwrap()
168 .iter_blocks();
169
170 self.section_iter_current.next()
171 }
172 Some(block) => Some(block),
173 };
174 }
175}