1use yog_data::{Atom, Schema};
5
6use crate::{BlockPos, Point};
7
8#[derive(Debug, Clone, PartialEq, Schema)]
10#[data(view)]
11pub struct LocalState {
12 pub pos: Point,
13 pub yaw: f32,
15 pub pitch: f32,
16 pub velocity: Point,
18 pub on_ground: bool,
19 pub in_water: bool,
20 pub eye_height: f64,
21 pub health: f32,
22 pub food: i32,
23 pub dimension: Atom,
24 pub slot: u32,
26 pub attack_strength: f32,
28}
29
30impl LocalState {
31 pub fn eye_pos(&self) -> Point {
33 Point {
34 y: self.pos.y + self.eye_height,
35 ..self.pos
36 }
37 }
38}
39
40#[derive(Debug, Clone, PartialEq, Schema)]
42#[data(view)]
43pub struct BlockKind {
44 pub id: Atom,
45 pub solid: bool,
47 pub liquid: bool,
48 pub climbable: bool,
50 pub harmful: bool,
52}
53
54#[derive(Debug, Clone, PartialEq, Schema)]
58#[data(view)]
59pub struct BlockArea {
60 pub min: BlockPos,
61 pub max: BlockPos,
62 pub palette: Vec<BlockKind>,
63 pub blocks: Vec<u16>,
64}
65
66impl BlockArea {
67 pub fn at(&self, pos: impl Into<BlockPos>) -> Option<&BlockKind> {
69 let pos = pos.into();
70 let (w, d) = (self.max.x - self.min.x + 1, self.max.z - self.min.z + 1);
71 let (x, y, z) = (pos.x - self.min.x, pos.y - self.min.y, pos.z - self.min.z);
72 let inside = (0..w).contains(&x)
73 && (0..d).contains(&z)
74 && (0..=self.max.y - self.min.y).contains(&y);
75 let index = inside
76 .then(|| self.blocks.get(((y * d + z) * w + x) as usize))
77 .flatten()?;
78 self.palette.get(usize::from(*index))
79 }
80}
81
82#[derive(Debug, Clone, PartialEq, Schema)]
84#[data(view)]
85pub struct NearbyEntity {
86 pub uuid: String,
87 pub entity_type: Atom,
88 pub pos: Point,
89 pub eye_height: f64,
90 pub velocity: Point,
92 pub health: Option<f32>,
93 pub name: Option<String>,
95 pub hostile: bool,
97}
98
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Schema)]
101pub enum ClickMode {
102 Pickup,
103 QuickMove,
104 Swap,
105 Clone,
106 Throw,
107 QuickCraft,
108 PickupAll,
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn an_area_finds_its_blocks() {
117 let kind = |id: &str| BlockKind {
118 id: id.into(),
119 solid: true,
120 liquid: false,
121 climbable: false,
122 harmful: false,
123 };
124 let area = BlockArea {
125 min: BlockPos::new(0, 0, 0),
126 max: BlockPos::new(1, 1, 0),
127 palette: vec![kind("a"), kind("b")],
128 blocks: vec![0, 1, 1, 0],
129 };
130 assert_eq!(
131 area.at(BlockPos::new(1, 0, 0)).map(|k| k.id.as_str()),
132 Some("b")
133 );
134 assert_eq!(
135 area.at(BlockPos::new(0, 1, 0)).map(|k| k.id.as_str()),
136 Some("b")
137 );
138 assert_eq!(area.at(BlockPos::new(2, 0, 0)), None);
139 }
140}