summaryrefslogtreecommitdiff
path: root/src/sim/sim.rs
blob: 350b823b1e0be703076710aed881cabe3883755a (plain)
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
use crate::{Board, sim::board::Cell};

pub struct UpdateCtx<'a> {
    pub self_x: i32,
    pub self_y: i32,
    pub self_cell: Cell,
    pub delta_time: f32,
    pub seqno_parity: u8,
    pub board: &'a mut Board,
}

impl UpdateCtx<'_> {
    pub fn candidates_swap(&mut self, candidates: &[(i32, i32)]) -> bool {
        for candidate in candidates {
            let target = self.board.cell_at_position(candidate.0, candidate.1);
            if let Some(target) = target
                && target.material.def().density < self.self_cell.material.def().density
            {
                // swap the cells
                self.board
                    .set_cell_at_position(self.self_x, self.self_y, target);
                self.board
                    .set_cell_at_position(candidate.0, candidate.1, self.self_cell);
                return true;
            }
        }
        false
    }
}

// TODO: chunks
pub fn sim_tick(board: &mut Board, seqno: u64, delta_time: f32) {
    // scan bottom to top to enable contiguous falling
    let seqno_parity = (seqno as u8) & 0b1;

    let bx = (board.size_x / 2) as i32;
    let by = (board.size_y / 2) as i32;
    for y in (-by..by + 1).rev() {
        // invert scan order on every other frame
        for col in -bx..bx + 1 {
            let x = if seqno_parity == 0 { col } else { -col };

            let cell = board.cell_at_position(x, y);
            if let Some(mut cur) = cell
                && cur.flags & 0b1 == seqno_parity
            {
                // flip the parity bit
                cur.flags = cur.flags ^ 0b1;

                if let Some(update) = cur.material.def().sim_update {
                    update(&mut UpdateCtx {
                        self_x: x,
                        self_y: y,
                        self_cell: cur,
                        board,
                        delta_time,
                        seqno_parity,
                    });
                }
            }
        }
    }
}