mindustry logic execution, map- and schematic- parsing and rendering
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::any::Any;

use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock};
use crate::block::{make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError};
use crate::data::dynamic::{DynData, DynType};
use crate::data::GridPos;
use crate::item::storage::Storage;

make_register!
(
    "copper-wall" => SimpleBlock::new(1, true, cost!(Copper: 6));
    "copper-wall-large" => SimpleBlock::new(2, true, cost!(Copper: 24));
    "titanium-wall" => SimpleBlock::new(1, true, cost!(Titanium: 6));
    "titanium-wall-large" => SimpleBlock::new(2, true, cost!(Titanium: 24));
    "plastanium-wall" => SimpleBlock::new(1, true, cost!(Metaglass: 2, Plastanium: 5));
    "plastanium-wall-large" => SimpleBlock::new(2, true, cost!(Metaglass: 8, Plastanium: 20));
    "thorium-wall" => SimpleBlock::new(1, true, cost!(Thorium: 6));
    "thorium-wall-large" => SimpleBlock::new(2, true, cost!(Thorium: 24));
    "phase-wall" => SimpleBlock::new(1, true, cost!(PhaseFabric: 6));
    "phase-wall-large" => SimpleBlock::new(2, true, cost!(PhaseFabric: 24));
    "surge-wall" => SimpleBlock::new(1, true, cost!(SurgeAlloy: 6));
    "surge-wall-large" => SimpleBlock::new(2, true, cost!(SurgeAlloy: 24));
    "door" => DoorBlock::new(1, true, cost!(Titanium: 6, Silicon: 4));
    "door-large" => DoorBlock::new(2, true, cost!(Titanium: 24, Silicon: 16));
    // sandbox only
    "scrap-wall" => SimpleBlock::new(1, true, cost!(Scrap: 6));
    "scrap-wall-large" => SimpleBlock::new(2, true, cost!(Scrap: 24));
    "scrap-wall-huge" => SimpleBlock::new(3, true, cost!(Scrap: 54));
    "scrap-wall-gigantic" => SimpleBlock::new(4, true, cost!(Scrap: 96));
    "thruster" => SimpleBlock::new(4, false, cost!(Scrap: 96));
);

pub struct DoorBlock {
    size: u8,
    symmetric: bool,
    build_cost: BuildCost,
}

impl DoorBlock {
    pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
        if size == 0 {
            panic!("invalid size");
        }
        Self {
            size,
            symmetric,
            build_cost,
        }
    }

    state_impl!(pub bool);
}

impl BlockLogic for DoorBlock {
    fn get_size(&self) -> u8 {
        self.size
    }

    fn is_symmetric(&self) -> bool {
        self.symmetric
    }

    fn create_build_cost(&self) -> Option<Storage> {
        if !self.build_cost.is_empty() {
            let mut storage = Storage::new();
            for (ty, cnt) in self.build_cost {
                storage.add(*ty, *cnt, u32::MAX);
            }
            Some(storage)
        } else {
            None
        }
    }

    fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
        Ok(DynData::Boolean(false))
    }

    fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> {
        match data {
            DynData::Boolean(opened) => Ok(Some(Self::create_state(opened))),
            _ => Err(DeserializeError::InvalidType {
                have: data.get_type(),
                expect: DynType::Boolean,
            }),
        }
    }

    fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> {
        let state = Self::get_state(state);
        Box::new(Self::create_state(*state))
    }

    fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {}

    fn rotate_state(&self, _: &mut dyn Any, _: bool) {}

    fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> {
        let state = Self::get_state(state);
        Ok(DynData::Boolean(*state))
    }
}