Skip to main content

fastanvil/complete/
section_tower.rs

1use 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        //first compute current section y then sub that from the ask y to get the y in the section
23        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        //first compute current section y then sub that from the ask y to get the y in the section
34        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        // This looks suspicious, we're not using the map of sections. #99
61        // This is only a problem because if there can be a terminating section
62        // in 1.18 worlds? It looks like that's not the case.
63        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        //needed to skip first because it seems like there is a sections to much in the list
84        // could be connected to java::section_tower.get_section_for_y -> todo
85        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                    &current_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                    &current_blocks[(index * BLOCK_COUNT)..((index + 1) * BLOCK_COUNT)],
125                    &current_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: &section_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                //check if it was the last section
159                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}