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