use yog_sync::LazyLock;
use yog_data::Ordered;
use yog_graphics::Color;
#[derive(yog_data::Schema, Debug, Clone, PartialEq, Default)]
pub struct LookModels {
pub potion: String,
pub spawn_egg: String,
pub heads: Vec<String>,
}
#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
pub struct ItemTint {
pub color: Color,
#[data(default)]
pub items: Vec<String>,
#[data(default)]
pub prefix: String,
}
#[derive(yog_data::Schema, Debug, Clone, PartialEq, Default)]
pub struct ItemLooks {
pub models: LookModels,
pub heads: Ordered<String>,
pub tints: Vec<ItemTint>,
pub spawn_eggs: Ordered<Vec<Color>>,
}
static ITEM_LOOKS: LazyLock<ItemLooks> = LazyLock::new(|| {
yog_data::built_in::<ItemLooks>(
"yog-registry's item looks",
include_str!("../../assets/item_looks.ydata"),
)
});
impl ItemLooks {
pub fn game() -> &'static ItemLooks {
&ITEM_LOOKS
}
pub fn head(&self, path: &str) -> Option<&str> {
self.heads
.0
.iter()
.find(|(p, _)| p == path)
.map(|(_, t)| t.as_str())
}
pub fn spawn_egg(&self, mob: &str) -> Option<(Color, Color)> {
match self
.spawn_eggs
.0
.iter()
.find(|(m, _)| m == mob)?
.1
.as_slice()
{
[base, spots] => Some((*base, *spots)),
_ => None,
}
}
pub fn tint(&self, id: &str) -> Option<Color> {
self.tints
.iter()
.find(|t| {
t.items.iter().any(|i| i == id)
|| (!t.prefix.is_empty() && id.starts_with(&t.prefix))
})
.map(|t| t.color)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_game_looks_read() {
let l = ItemLooks::game();
assert_eq!(
l.head("zombie_head"),
Some("minecraft:entity/zombie/zombie")
);
assert_eq!(
l.spawn_egg("creeper"),
Some((Color(0xFF0D_A70B), Color(0xFF00_0000)))
);
assert_eq!(l.tint("minecraft:potion"), Some(Color(0xFF38_5DC6)));
assert_eq!(l.tint("minecraft:leather_boots"), Some(Color(0xFFA0_6540)));
}
}