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
103
104
105
106
107
108
use num_enum::{IntoPrimitive, TryFromPrimitive};
use std::fmt;
use uuid::Uuid;

/// A single brick in a save file.
///
/// `asset_name_index`, `material_index`, `owner_index` and the `Set` variant
/// of `color` target the lookup tables in either
/// [`WriteData`](struct.WriteData.html) or the headers, when reading.
///
/// `size` is used for procedural bricks. For fixed size brick assets, it's
/// more efficient to use `(0, 0, 0)` (the file will be smaller).
#[derive(Debug, Clone, PartialEq)]
pub struct Brick {
    pub asset_name_index: u32,
    pub size: (u32, u32, u32),
    pub position: (i32, i32, i32),
    pub direction: Direction,
    pub rotation: Rotation,
    pub collision: bool,
    pub visibility: bool,
    pub material_index: u32,
    pub color: ColorMode,
    pub owner_index: u32,
}

#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
pub enum Direction {
    XPositive,
    XNegative,
    YPositive,
    YNegative,
    ZPositive,
    ZNegative,
}

#[repr(u8)]
#[derive(
    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, IntoPrimitive, TryFromPrimitive,
)]
pub enum Rotation {
    Deg0,
    Deg90,
    Deg180,
    Deg270,
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ColorMode {
    /// A color from the color lookup table.
    Set(u32),
    /// A custom color.
    Custom(Color),
}

/// Represents a RGBA color.
#[derive(Clone, Copy, PartialEq, Hash)]
pub struct Color(u32);

impl Color {
    pub fn from_rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
        Self(u32::from(b) | (u32::from(g) << 8) | (u32::from(r) << 16) | (u32::from(a) << 24))
    }
    pub fn r(self) -> u8 {
        ((self.0 >> 16) & 0xff) as u8
    }
    pub fn g(self) -> u8 {
        ((self.0 >> 8) & 0xff) as u8
    }
    pub fn b(self) -> u8 {
        (self.0 & 0xff) as u8
    }
    pub fn a(self) -> u8 {
        ((self.0 >> 24) & 0xff) as u8
    }
}

impl Into<Color> for u32 {
    fn into(self) -> Color {
        Color(self)
    }
}

impl Into<u32> for Color {
    fn into(self) -> u32 {
        self.0
    }
}

impl fmt::Debug for Color {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "#{:02x}{:02x}{:02x}{:02x}",
            self.r(),
            self.g(),
            self.b(),
            self.a()
        )
    }
}

#[derive(Debug, Clone, PartialEq, Hash)]
pub struct User {
    pub id: Uuid,
    pub name: String,
}