steel_protocol/packets/game/
c_sound.rs1use glam::{DVec3, IVec3};
2use steel_macros::{ClientPacket, WriteTo};
3use steel_registry::packets::play::C_SOUND;
4use steel_registry::sound_event::SoundEventRef;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8#[repr(u8)]
9pub enum SoundSource {
10 Master = 0,
11 Music = 1,
12 Records = 2,
13 Weather = 3,
14 Blocks = 4,
15 Hostile = 5,
16 Neutral = 6,
17 Players = 7,
18 Ambient = 8,
19 Voice = 9,
20 Ui = 10,
21}
22
23impl SoundSource {
24 #[must_use]
26 pub const fn as_varint(self) -> i32 {
27 self as i32
28 }
29}
30
31#[derive(WriteTo, ClientPacket, Clone, Debug)]
36#[packet_id(Play = C_SOUND)]
37pub struct CSound {
38 #[write(as = VarInt)]
43 pub sound_id: i32,
44 #[write(as = VarInt)]
46 pub source: i32,
47 pub pos: IVec3,
49 pub volume: f32,
51 pub pitch: f32,
53 pub seed: i64,
55}
56
57impl CSound {
58 #[must_use]
68 pub fn new(
69 sound: SoundEventRef,
70 source: SoundSource,
71 pos: DVec3,
72 volume: f32,
73 pitch: f32,
74 seed: i64,
75 ) -> Self {
76 Self {
77 sound_id: sound.packet_holder_id(),
78 source: source.as_varint(),
79 pos: IVec3::new(
80 (pos.x * 8.0) as i32,
81 (pos.y * 8.0) as i32,
82 (pos.z * 8.0) as i32,
83 ),
84 volume,
85 pitch,
86 seed,
87 }
88 }
89
90 #[must_use]
99 pub fn block_sound(
100 sound: SoundEventRef,
101 pos: steel_utils::BlockPos,
102 volume: f32,
103 pitch: f32,
104 seed: i64,
105 ) -> Self {
106 Self::new(
107 sound,
108 SoundSource::Blocks,
109 pos.0.as_dvec3().map(|v| v + 0.5),
110 volume,
111 pitch,
112 seed,
113 )
114 }
115}
116
117#[cfg(test)]
118mod tests {
119
120 use steel_registry::init_vanilla_registry;
121 use steel_registry::{RegistryEntry, sound_events};
122 use steel_utils::BlockPos;
123
124 use super::CSound;
125
126 #[test]
127 fn registered_sound_packet_uses_holder_id() {
128 init_vanilla_registry();
129
130 let packet = CSound::block_sound(
131 &sound_events::BLOCK_WOODEN_BUTTON_CLICK_ON,
132 BlockPos::ZERO,
133 1.0,
134 1.0,
135 0,
136 );
137
138 let expected_holder_id = sound_events::BLOCK_WOODEN_BUTTON_CLICK_ON.id() as i32 + 1;
139 assert_eq!(
140 sound_events::BLOCK_WOODEN_BUTTON_CLICK_ON.packet_holder_id(),
141 expected_holder_id
142 );
143 assert_eq!(packet.sound_id, expected_holder_id);
144 }
145}