azalea_protocol/packets/game/
c_boss_event.rs

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