use yog_ids::tool_kind::{AXE, HOE, PICKAXE, SHOVEL, SWORD};
#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
pub struct ToolItem {
pub kind: String,
pub material: String,
pub attack_damage: Option<f32>,
pub attack_speed: Option<f32>,
}
pub const DIGGERS: [&str; 4] = [PICKAXE, AXE, SHOVEL, HOE];
pub const TOOL_KINDS: [&str; 5] = [PICKAXE, AXE, SHOVEL, HOE, SWORD];
pub const REFERENCE_MATERIAL: &str = yog_ids::id!(yog_ids::ns::MINECRAFT, "iron");
pub const REFERENCE_KIND: &str = PICKAXE;
#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
pub struct GameTool {
pub item: String,
pub material_damage: f32,
}
#[derive(yog_data::Schema, Debug, Clone, Copy, PartialEq, Eq)]
pub enum ArmorSlot {
Head,
Chest,
Legs,
Feet,
}
#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
pub struct ArmorPiece {
pub slot: ArmorSlot,
pub material: String,
}
#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
pub struct ToolMaterial {
pub id: String,
pub durability: u32,
pub speed: f32,
pub attack_damage: f32,
pub enchantability: u32,
pub level: String,
pub repair: String,
#[data(default)]
pub level_index: u32,
#[data(default)]
pub incorrect: String,
#[data(default)]
pub game_tools: String,
}
#[derive(yog_data::Schema, Debug, Clone, Copy, PartialEq)]
pub struct ArmorDefense {
pub head: u32,
pub chest: u32,
pub legs: u32,
pub feet: u32,
}
#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
pub struct ArmorMaterial {
pub id: String,
pub durability: u32,
pub defense: ArmorDefense,
pub enchantability: u32,
pub equip_sound: String,
#[data(default)]
pub toughness: f32,
#[data(default)]
pub knockback_resistance: f32,
pub repair: String,
pub texture: String,
}
static BUILT_IN_TOOL_MATERIALS: yog_sync::LazyLock<Vec<ToolMaterial>> =
yog_sync::LazyLock::new(|| {
yog_data::built_in::<Vec<ToolMaterial>>(
"yog-registry's built-in tool materials",
include_str!("../../assets/tool_materials.ydata"),
)
});
static BUILT_IN_ARMOR_MATERIALS: yog_sync::LazyLock<Vec<ArmorMaterial>> =
yog_sync::LazyLock::new(|| {
yog_data::built_in::<Vec<ArmorMaterial>>(
"yog-registry's built-in armor materials",
include_str!("../../assets/armor_materials.ydata"),
)
});
pub(crate) fn built_in<'a, T>(list: &'a [T], id: impl Fn(&T) -> &str, name: &str) -> Option<&'a T> {
let name = yog_ids::qualify(name);
list.iter().find(|x| id(x) == name)
}
impl ToolMaterial {
pub fn built_ins() -> &'static [ToolMaterial] {
&BUILT_IN_TOOL_MATERIALS
}
pub fn built_in(name: &str) -> Option<&'static ToolMaterial> {
built_in(Self::built_ins(), |m| &m.id, name)
}
pub fn like(id: impl Into<String>, like: &str) -> Option<Self> {
let mut m = Self::built_in(like)?.clone();
m.id = id.into();
Some(m)
}
pub fn game_tool(&self, kind: &str) -> Option<GameTool> {
let made = if self.game_tools.is_empty() {
Self::built_in(REFERENCE_MATERIAL)?
} else {
Self::built_ins()
.iter()
.find(|m| m.game_tools == self.game_tools)?
};
let kind = if TOOL_KINDS.contains(&kind) {
kind
} else {
REFERENCE_KIND
};
Some(GameTool {
item: yog_ids::qualify(&format!("{}{kind}", made.game_tools)),
material_damage: made.attack_damage,
})
}
}
impl ArmorMaterial {
pub fn built_ins() -> &'static [ArmorMaterial] {
&BUILT_IN_ARMOR_MATERIALS
}
pub fn built_in(name: &str) -> Option<&'static ArmorMaterial> {
built_in(Self::built_ins(), |m| &m.id, name)
}
}