azalea_protocol/packets/game/
c_boss_event.rs

1use std::io::Cursor;
2use std::io::Write;
3
4use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
5use azalea_chat::FormattedText;
6use azalea_core::bitset::FixedBitSet;
7use azalea_protocol_macros::ClientboundGamePacket;
8use uuid::Uuid;
9
10#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)]
11pub struct ClientboundBossEvent {
12    pub id: Uuid,
13    pub operation: Operation,
14}
15
16#[derive(Clone, Debug)]
17pub enum Operation {
18    Add(AddOperation),
19    Remove,
20    UpdateProgress(f32),
21    UpdateName(FormattedText),
22    UpdateStyle(Style),
23    UpdateProperties(Properties),
24}
25
26impl AzaleaRead for Operation {
27    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
28        let operation_id = u32::azalea_read_var(buf)?;
29        Ok(match operation_id {
30            0 => Operation::Add(AddOperation::azalea_read(buf)?),
31            1 => Operation::Remove,
32            2 => Operation::UpdateProgress(f32::azalea_read(buf)?),
33            3 => Operation::UpdateName(FormattedText::azalea_read(buf)?),
34            4 => Operation::UpdateStyle(Style::azalea_read(buf)?),
35            5 => Operation::UpdateProperties(Properties::azalea_read(buf)?),
36            _ => {
37                return Err(BufReadError::UnexpectedEnumVariant {
38                    id: operation_id as i32,
39                })
40            }
41        })
42    }
43}
44
45impl AzaleaWrite for Operation {
46    fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
47        match self {
48            Operation::Add(add) => {
49                0u32.azalea_write_var(buf)?;
50                add.azalea_write(buf)?;
51            }
52            Operation::Remove => {
53                1u32.azalea_write_var(buf)?;
54            }
55            Operation::UpdateProgress(progress) => {
56                2u32.azalea_write_var(buf)?;
57                progress.azalea_write(buf)?;
58            }
59            Operation::UpdateName(name) => {
60                3u32.azalea_write_var(buf)?;
61                name.azalea_write(buf)?;
62            }
63            Operation::UpdateStyle(style) => {
64                4u32.azalea_write_var(buf)?;
65                style.azalea_write(buf)?;
66            }
67            Operation::UpdateProperties(properties) => {
68                5u32.azalea_write_var(buf)?;
69                properties.azalea_write(buf)?;
70            }
71        }
72        Ok(())
73    }
74}
75
76#[derive(Clone, Debug, AzBuf)]
77pub struct AddOperation {
78    pub name: FormattedText,
79    pub progress: f32,
80    pub style: Style,
81    pub properties: Properties,
82}
83
84#[derive(Clone, Debug, AzBuf)]
85pub struct Style {
86    pub color: BossBarColor,
87    pub overlay: BossBarOverlay,
88}
89
90#[derive(AzBuf, Clone, Copy, Debug)]
91pub enum BossBarColor {
92    Pink = 0,
93    Blue = 1,
94    Red = 2,
95    Green = 3,
96    Yellow = 4,
97    Purple = 5,
98    White = 6,
99}
100
101#[derive(AzBuf, Clone, Copy, Debug)]
102pub enum BossBarOverlay {
103    Progress = 0,
104    Notched6 = 1,
105    Notched10 = 2,
106    Notched12 = 3,
107    Notched20 = 4,
108}
109
110#[derive(Clone, Debug)]
111pub struct Properties {
112    pub darken_screen: bool,
113    pub play_music: bool,
114    pub create_world_fog: bool,
115}
116
117impl AzaleaRead for Properties {
118    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
119        let set = FixedBitSet::<{ 3_usize.div_ceil(8) }>::azalea_read(buf)?;
120        Ok(Self {
121            darken_screen: set.index(0),
122            play_music: set.index(1),
123            create_world_fog: set.index(2),
124        })
125    }
126}
127
128impl AzaleaWrite for Properties {
129    fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
130        let mut set = FixedBitSet::<{ 3_usize.div_ceil(8) }>::new();
131        if self.darken_screen {
132            set.set(0);
133        }
134        if self.play_music {
135            set.set(1);
136        }
137        if self.create_world_fog {
138            set.set(2);
139        }
140        set.azalea_write(buf)?;
141        Ok(())
142    }
143}