summaryrefslogtreecommitdiff
path: root/server/editor/src/save.rs
blob: a77cd60909b6c576c957edf05ce209dd129d6af7 (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
64
65
66
67
68
69
use crate::{State, TILES};
use hurrycurry_protocol::glam::{IVec2, ivec2};
use serde::Serialize;
use std::collections::{HashMap, HashSet};

#[rustfmt::skip]
#[derive(Debug, Clone, Serialize)]
pub struct MapDecl {
    map: Vec<String>,
    tiles: HashMap<char, String>,
    items: HashMap<char, String>,
    collider: Vec<String>,
    walkable: Vec<String>,
    chef_spawn: char,
    customer_spawn: char,
    score_baseline: i64,
}

pub fn export_state(state: &State) -> String {
    let mut cmin = IVec2::MAX;
    let mut cmax = IVec2::MIN;
    for pos in state.tiles.keys().copied() {
        cmin = cmin.min(pos);
        cmax = cmax.max(pos);
    }

    let mut map = Vec::new();
    let mut tiles = HashMap::new();
    let mut collider = HashSet::new();
    let mut walkable = HashSet::new();
    for y in cmin.y..=cmax.y {
        let mut line = String::new();
        for x in cmin.x..=cmax.x {
            let p = ivec2(x, y);
            line.push(if let Some(t) = state.tiles.get(&p) {
                let c = if p == state.chef_spawn {
                    '~'
                } else if p == state.customer_spawn {
                    '!'
                } else {
                    TILES[t.0].1
                };
                if TILES[t.0].2 == 2 {
                    collider.insert(TILES[t.0].0.to_string());
                }
                if TILES[t.0].2 == 1 {
                    walkable.insert(TILES[t.0].0.to_string());
                }
                tiles.insert(c, TILES[t.0].0.to_string());
                c
            } else {
                ' '
            })
        }
        map.push(line);
    }

    let decl: MapDecl = MapDecl {
        map,
        tiles,
        items: HashMap::new(),
        collider: collider.into_iter().collect(),
        walkable: walkable.into_iter().collect(),
        chef_spawn: '~',
        customer_spawn: '!',
        score_baseline: 200,
    };
    serde_yml::to_string(&decl).unwrap()
}