steel_registry/data_components/components/
rgb_color.rs1use simdnbt::owned::NbtTag;
4use steel_utils::nbt::{NbtNumeric as _, nbt_collection_values};
5
6pub(super) fn decode_rgb_color(tag: &NbtTag) -> Option<i32> {
7 if let Some(color) = tag.codec_i32() {
8 return Some(color);
9 }
10 let channels = nbt_collection_values(tag)?;
11 let [red, green, blue] = channels.as_slice() else {
12 return None;
13 };
14 Some(rgb_from_floats(
15 red.codec_f32()?,
16 green.codec_f32()?,
17 blue.codec_f32()?,
18 ))
19}
20
21fn rgb_from_floats(red: f32, green: f32, blue: f32) -> i32 {
22 let red = java_floor(red * 255.0) & 0xff;
23 let green = java_floor(green * 255.0) & 0xff;
24 let blue = java_floor(blue * 255.0) & 0xff;
25 (0xff00_0000_u32 | ((red as u32) << 16) | ((green as u32) << 8) | blue as u32) as i32
26}
27
28fn java_floor(value: f32) -> i32 {
29 let truncated = value as i32;
30 if value < truncated as f32 {
31 truncated.wrapping_sub(1)
32 } else {
33 truncated
34 }
35}