1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
use std::collections::HashMap;
use crate::{
config::CHUNK_SIZE,
sim::{cell::Cell, chunk::Chunk},
};
pub struct World {
pub chunks: Vec<Chunk>,
// TODO FxHashMap?
pub chunk_position_to_chunk_idx: HashMap<(i32, i32), usize>,
}
impl World {
#[inline]
pub fn split_game_position(x: i32, y: i32) -> ((i32, i32), (u8, u8)) {
(
(
// TODO is this cast expensive?
x.div_euclid(CHUNK_SIZE as i32),
y.div_euclid(CHUNK_SIZE as i32),
),
(
x.rem_euclid(CHUNK_SIZE as i32) as u8,
y.rem_euclid(CHUNK_SIZE as i32) as u8,
),
)
}
// VERY EXPENSIVE
pub fn get_cell_from_game_position(&self, x: i32, y: i32) -> Option<Cell> {
let ((cx, cy), (dx, dy)) = World::split_game_position(x, y);
self.chunk_position_to_chunk_idx
.get(&(cx, cy))
.map(|&idx| self.chunks[idx].get_cell_at_local_position(dx, dy))
}
// VERY EXPENSIVE
pub fn set_cell_from_game_position(
&mut self,
x: i32,
y: i32,
cell: Cell,
sleeping: bool,
) -> () {
let ((cx, cy), (dx, dy)) = World::split_game_position(x, y);
if let Some(&idx) = self.chunk_position_to_chunk_idx.get(&(cx, cy)) {
self.chunks[idx].set_cell_at_local_position(dx, dy, cell);
// this is a temporary hack
self.chunks[idx].sleeping = sleeping;
}
}
pub fn insert(&mut self, x: i32, y: i32, chunk: Chunk) -> () {
self.chunk_position_to_chunk_idx
.insert((x, y), self.chunks.len());
self.chunks.push(chunk);
}
pub fn from_default_size() -> Self {
let mut world = World {
chunks: Vec::new(),
chunk_position_to_chunk_idx: HashMap::new(),
};
for y in -10..10 {
for x in -50..50 {
world.insert(x, y, Chunk::void());
}
}
world
}
}
|