1use yog_ids::tool_kind::{AXE, HOE, PICKAXE, SHOVEL, SWORD};
4
5#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
7pub struct ToolItem {
8 pub kind: String,
11 pub material: String,
13 pub attack_damage: Option<f32>,
16 pub attack_speed: Option<f32>,
18}
19
20pub const DIGGERS: [&str; 4] = [PICKAXE, AXE, SHOVEL, HOE];
22pub const TOOL_KINDS: [&str; 5] = [PICKAXE, AXE, SHOVEL, HOE, SWORD];
24
25pub const REFERENCE_MATERIAL: &str = yog_ids::id!(yog_ids::ns::MINECRAFT, "iron");
28pub const REFERENCE_KIND: &str = PICKAXE;
29
30#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
34pub struct GameTool {
35 pub item: String,
36 pub material_damage: f32,
37}
38
39#[derive(yog_data::Schema, Debug, Clone, Copy, PartialEq, Eq)]
41pub enum ArmorSlot {
42 Head,
43 Chest,
44 Legs,
45 Feet,
46}
47
48#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
50pub struct ArmorPiece {
51 pub slot: ArmorSlot,
52 pub material: String,
54}
55
56#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
61pub struct ToolMaterial {
62 pub id: String,
63 pub durability: u32,
65 pub speed: f32,
67 pub attack_damage: f32,
69 pub enchantability: u32,
70 pub level: String,
72 pub repair: String,
74 #[data(default)]
76 pub level_index: u32,
77 #[data(default)]
80 pub incorrect: String,
81 #[data(default)]
84 pub game_tools: String,
85}
86
87#[derive(yog_data::Schema, Debug, Clone, Copy, PartialEq)]
89pub struct ArmorDefense {
90 pub head: u32,
91 pub chest: u32,
92 pub legs: u32,
93 pub feet: u32,
94}
95
96#[derive(yog_data::Schema, Debug, Clone, PartialEq)]
100pub struct ArmorMaterial {
101 pub id: String,
102 pub durability: u32,
105 pub defense: ArmorDefense,
106 pub enchantability: u32,
107 pub equip_sound: String,
109 #[data(default)]
110 pub toughness: f32,
111 #[data(default)]
112 pub knockback_resistance: f32,
113 pub repair: String,
115 pub texture: String,
118}
119
120static BUILT_IN_TOOL_MATERIALS: yog_sync::LazyLock<Vec<ToolMaterial>> =
121 yog_sync::LazyLock::new(|| {
122 yog_data::built_in::<Vec<ToolMaterial>>(
123 "yog-registry's built-in tool materials",
124 include_str!("../assets/tool_materials.ydata"),
125 )
126 });
127
128static BUILT_IN_ARMOR_MATERIALS: yog_sync::LazyLock<Vec<ArmorMaterial>> =
129 yog_sync::LazyLock::new(|| {
130 yog_data::built_in::<Vec<ArmorMaterial>>(
131 "yog-registry's built-in armor materials",
132 include_str!("../assets/armor_materials.ydata"),
133 )
134 });
135
136pub(crate) fn built_in<'a, T>(list: &'a [T], id: impl Fn(&T) -> &str, name: &str) -> Option<&'a T> {
138 let name = yog_ids::qualify(name);
139 list.iter().find(|x| id(x) == name)
140}
141
142impl ToolMaterial {
143 pub fn built_ins() -> &'static [ToolMaterial] {
145 &BUILT_IN_TOOL_MATERIALS
146 }
147
148 pub fn built_in(name: &str) -> Option<&'static ToolMaterial> {
150 built_in(Self::built_ins(), |m| &m.id, name)
151 }
152
153 pub fn like(id: impl Into<String>, like: &str) -> Option<Self> {
156 let mut m = Self::built_in(like)?.clone();
157 m.id = id.into();
158 Some(m)
159 }
160
161 pub fn game_tool(&self, kind: &str) -> Option<GameTool> {
164 let made = if self.game_tools.is_empty() {
165 Self::built_in(REFERENCE_MATERIAL)?
166 } else {
167 Self::built_ins()
168 .iter()
169 .find(|m| m.game_tools == self.game_tools)?
170 };
171 let kind = if TOOL_KINDS.contains(&kind) {
172 kind
173 } else {
174 REFERENCE_KIND
175 };
176 Some(GameTool {
177 item: yog_ids::qualify(&format!("{}{kind}", made.game_tools)),
178 material_damage: made.attack_damage,
179 })
180 }
181}
182
183impl ArmorMaterial {
184 pub fn built_ins() -> &'static [ArmorMaterial] {
186 &BUILT_IN_ARMOR_MATERIALS
187 }
188
189 pub fn built_in(name: &str) -> Option<&'static ArmorMaterial> {
191 built_in(Self::built_ins(), |m| &m.id, name)
192 }
193}