azalea_block/
fluid_state.rs1use crate::block_state::{BlockState, BlockStateIntegerRepr};
2
3#[derive(Clone, Debug)]
4pub struct FluidState {
5 pub kind: FluidKind,
6 pub amount: u8,
15
16 pub falling: bool,
22}
23#[derive(Default, Clone, Debug, PartialEq, Eq)]
24pub enum FluidKind {
25 #[default]
26 Empty,
27 Water,
28 Lava,
29}
30impl FluidState {
31 pub fn new_source_block(kind: FluidKind, falling: bool) -> Self {
32 Self {
33 kind,
34 amount: 8,
35 falling,
36 }
37 }
38
39 pub fn height(&self) -> f32 {
42 self.amount as f32 / 9.
43 }
44 pub fn is_empty(&self) -> bool {
45 self.amount == 0
46 }
47
48 pub fn affects_flow(&self, other: &FluidState) -> bool {
49 other.amount == 0 || self.is_same_kind(other)
50 }
51
52 pub fn is_same_kind(&self, other: &FluidState) -> bool {
53 (other.kind == self.kind) || (self.amount == 0 && other.amount == 0)
54 }
55}
56
57impl Default for FluidState {
58 fn default() -> Self {
59 Self {
60 kind: FluidKind::Empty,
61 amount: 0,
62 falling: false,
63 }
64 }
65}
66
67impl From<BlockState> for FluidState {
68 fn from(state: BlockState) -> Self {
69 if state
73 .property::<crate::properties::Waterlogged>()
74 .unwrap_or_default()
75 {
76 return Self {
77 kind: FluidKind::Water,
78 amount: 8,
79 falling: false,
80 };
81 }
82
83 let registry_block = azalea_registry::Block::from(state);
84 match registry_block {
85 azalea_registry::Block::Water => {
86 let level = state
87 .property::<crate::properties::WaterLevel>()
88 .expect("water block should always have WaterLevel");
89 return Self {
90 kind: FluidKind::Water,
91 amount: to_or_from_legacy_fluid_level(level as u8),
92 falling: false,
93 };
94 }
95 azalea_registry::Block::Lava => {
96 let level = state
97 .property::<crate::properties::LavaLevel>()
98 .expect("lava block should always have LavaLevel");
99 return Self {
100 kind: FluidKind::Lava,
101 amount: to_or_from_legacy_fluid_level(level as u8),
102 falling: false,
103 };
104 }
105 azalea_registry::Block::BubbleColumn => {
106 return Self::new_source_block(FluidKind::Water, false);
107 }
108 _ => {}
109 }
110
111 Self::default()
112 }
113}
114
115pub fn to_or_from_legacy_fluid_level(level: u8) -> u8 {
121 8_u8.saturating_sub(level)
123}
124
125impl From<FluidState> for BlockState {
126 fn from(state: FluidState) -> Self {
127 match state.kind {
128 FluidKind::Empty => BlockState::AIR,
129 FluidKind::Water => BlockState::from(crate::blocks::Water {
130 level: crate::properties::WaterLevel::from(state.amount as BlockStateIntegerRepr),
131 }),
132 FluidKind::Lava => BlockState::from(crate::blocks::Lava {
133 level: crate::properties::LavaLevel::from(state.amount as BlockStateIntegerRepr),
134 }),
135 }
136 }
137}