|
@@ -1,116 +1,129 @@
|
|
|
-use crate::Tile;
|
|
|
-use std::ops::{Index, IndexMut};
|
|
|
+use std::{cmp::Ordering::Greater, fmt::{Debug, Display}, ops::{Index, IndexMut}};
|
|
|
+use point::Point;
|
|
|
+use serde::{Deserialize, Serialize};
|
|
|
|
|
|
-struct ChunkRow {
|
|
|
- pub row: [Tile; 32],
|
|
|
- pub empty: bool
|
|
|
+#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
|
|
+pub struct Chunk {
|
|
|
+ tiles: Vec<u64>
|
|
|
}
|
|
|
|
|
|
-impl ChunkRow {
|
|
|
- pub fn rescan_empty(&mut self) {
|
|
|
- let mut now_empty: bool = true;
|
|
|
- for i in 1..=32_usize {
|
|
|
- if self[i].is_visible() {
|
|
|
- now_empty = false;
|
|
|
- }
|
|
|
- }
|
|
|
- if now_empty {
|
|
|
- self.empty = true;
|
|
|
- } else {
|
|
|
- self.empty = false;
|
|
|
- }
|
|
|
- }
|
|
|
- pub fn is_empty(&self) -> bool {
|
|
|
- self.empty
|
|
|
- }
|
|
|
- pub fn set(&mut self, idx: usize, t: Tile) -> bool {
|
|
|
- if idx > 32 {
|
|
|
- return false;
|
|
|
- }
|
|
|
- if t.is_visible() {
|
|
|
- self.empty = false;
|
|
|
- } else {
|
|
|
- let mut now_empty: bool = true;
|
|
|
- for i in 1..=32_usize {
|
|
|
- if i == idx {
|
|
|
- continue;
|
|
|
- }
|
|
|
- if self[i].is_visible() {
|
|
|
- now_empty = false;
|
|
|
- }
|
|
|
- }
|
|
|
- if now_empty {
|
|
|
- self.empty = true;
|
|
|
- } else {
|
|
|
- self.empty = false;
|
|
|
- }
|
|
|
- }
|
|
|
- if idx == 0 {
|
|
|
- if !t.is_visible() {
|
|
|
- self.empty = true;
|
|
|
- }
|
|
|
- self.row.fill(t);
|
|
|
- return true;
|
|
|
+impl Index<Point<u64>> for Chunk {
|
|
|
+ type Output = u64;
|
|
|
+ fn index(&self, index: Point<u64>) -> &Self::Output {
|
|
|
+ let idx = index.distance_value();
|
|
|
+ if idx >= 32*32 {
|
|
|
+ panic!("index out of bounds");
|
|
|
}
|
|
|
- self.row[idx-1] = t;
|
|
|
- true
|
|
|
- }
|
|
|
- pub fn get(&self, idx: usize) -> Option<Tile> {
|
|
|
- if idx > 32 || idx == 0 {
|
|
|
- return None;
|
|
|
- }
|
|
|
- Some(self.row[idx-1].clone())
|
|
|
+ &self.tiles[idx as usize]
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Index<usize> for ChunkRow {
|
|
|
- type Output = Tile;
|
|
|
- fn index(&self, index: usize) -> &Self::Output {
|
|
|
- &self.row[index-1]
|
|
|
+impl IndexMut<Point<u64>> for Chunk {
|
|
|
+ fn index_mut(&mut self, index: Point<u64>) -> &mut Self::Output {
|
|
|
+ let idx = index.distance_value();
|
|
|
+ if idx >= 32*32 {
|
|
|
+ panic!("index out of bounds");
|
|
|
+ }
|
|
|
+ &mut self.tiles[idx as usize]
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl IndexMut<usize> for ChunkRow {
|
|
|
- fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
|
|
- &mut self.row[index-1]
|
|
|
+impl Index<&Point<u64>> for Chunk {
|
|
|
+ type Output = u64;
|
|
|
+ fn index(&self, index: &Point<u64>) -> &Self::Output {
|
|
|
+ let idx = index.distance_value();
|
|
|
+ if idx >= 32*32 {
|
|
|
+ panic!("index out of bounds");
|
|
|
+ }
|
|
|
+ &self.tiles[idx as usize]
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub struct Chunk {
|
|
|
- row: [ChunkRow; 32]
|
|
|
+impl IndexMut<&Point<u64>> for Chunk {
|
|
|
+ fn index_mut(&mut self, index: &Point<u64>) -> &mut Self::Output {
|
|
|
+ let idx = index.distance_value();
|
|
|
+ if idx >= 32*32 {
|
|
|
+ panic!("index out of bounds");
|
|
|
+ }
|
|
|
+ &mut self.tiles[idx as usize]
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl Chunk {
|
|
|
- pub fn rescan_empty(&mut self) {
|
|
|
- for i in 1..=32_usize {
|
|
|
- self.row[i-1].rescan_empty();
|
|
|
+ pub fn new() -> Self {
|
|
|
+ let mut s = Self { tiles: Vec::with_capacity(1024) };
|
|
|
+ s.tiles.extend_from_slice(&[0u64; 1024]);
|
|
|
+ s
|
|
|
+ }
|
|
|
+ pub fn new_filled(value: u64) -> Self {
|
|
|
+ let mut s = Self { tiles: Vec::with_capacity(1024) };
|
|
|
+ s.tiles.extend_from_slice(&[value; 1024]);
|
|
|
+ s
|
|
|
+ }
|
|
|
+ pub fn get(&self, pos: &Point<u64>) -> Option<&u64> {
|
|
|
+ let idx = pos.distance_value();
|
|
|
+ if idx >= 32*32 {
|
|
|
+ return None;
|
|
|
}
|
|
|
+ self.tiles.get(idx as usize)
|
|
|
}
|
|
|
- pub fn is_empty(&self) -> bool {
|
|
|
- for i in 1..=32_usize {
|
|
|
- if !self.row[i-1].is_empty() {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ pub fn get_mut(&mut self, pos: &Point<u64>) -> Option<&mut u64> {
|
|
|
+ let idx = pos.distance_value();
|
|
|
+ if idx >= 32*32 {
|
|
|
+ return None;
|
|
|
+ }
|
|
|
+ self.tiles.get_mut(idx as usize)
|
|
|
+ }
|
|
|
+ pub fn set(&mut self, pos: &Point<u64>, value: u64) -> bool {
|
|
|
+ let idx = pos.distance_value();
|
|
|
+ if idx >= 32*32 {
|
|
|
+ return false;
|
|
|
}
|
|
|
+ self.tiles[idx as usize] = value;
|
|
|
true
|
|
|
}
|
|
|
- pub fn is_row_empty(&self, idx: usize) -> bool {
|
|
|
- if idx > 32 || idx == 0 {
|
|
|
+ pub fn fill(&mut self, pos1: &Point<u64>, pos2: &Point<u64>, value: u64) -> bool {
|
|
|
+ let (corn1, corn2) = match pos1.partial_cmp(pos2).unwrap() {
|
|
|
+ Greater => {
|
|
|
+ (pos2.distance_value(), pos1.distance_value())
|
|
|
+ },
|
|
|
+ _ => {
|
|
|
+ (pos1.distance_value(), pos2.distance_value())
|
|
|
+ }
|
|
|
+ };
|
|
|
+ if corn1 >= 32*32 || corn2 >= 32*32 {
|
|
|
return false;
|
|
|
}
|
|
|
- self.row[idx-1].is_empty()
|
|
|
+ for idx in corn1..corn2 {
|
|
|
+ self.tiles[idx as usize] = value;
|
|
|
+ }
|
|
|
+ true
|
|
|
+ }
|
|
|
+ pub fn fill_all(&mut self, value: u64) {
|
|
|
+ self.tiles.clear();
|
|
|
+ self.tiles.extend_from_slice(&[value; 1024]);
|
|
|
+ }
|
|
|
+ pub fn clear(&mut self) {
|
|
|
+ self.tiles.clear();
|
|
|
+ self.tiles.extend_from_slice(&[0u64; 1024]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Index<(usize, usize)> for Chunk {
|
|
|
- type Output = Tile;
|
|
|
- fn index(&self, index: (usize, usize)) -> &Self::Output {
|
|
|
- &self.row[index.1][index.0]
|
|
|
+impl Default for Chunk {
|
|
|
+ fn default() -> Self {
|
|
|
+ Self::new()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl IndexMut<(usize, usize)> for Chunk {
|
|
|
- fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
|
|
|
- &mut self.row[index.1][index.0]
|
|
|
+impl Display for Chunk {
|
|
|
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
+ for y in 0..32u64 {
|
|
|
+ for x in 0..32u64 {
|
|
|
+ let idx = (x + y) as usize;
|
|
|
+ f.write_str(format!("{}", self.tiles[idx]).as_str())?;
|
|
|
+ }
|
|
|
+ f.write_str("\r\n")?;
|
|
|
+ }
|
|
|
+ Ok(())
|
|
|
}
|
|
|
}
|