#[derive(Debug, Clone)]
pub struct FoodDef {
pub nutrition: u32,
pub saturation: f32,
pub can_always_eat: bool,
}
impl FoodDef {
pub fn new(nutrition: u32, saturation: f32) -> Self {
Self { nutrition, saturation, can_always_eat: false }
}
pub fn can_always_eat(mut self) -> Self {
self.can_always_eat = true;
self
}
}
#[derive(Debug, Clone)]
pub struct ItemDef {
pub id: String,
pub max_stack: u8,
pub name: Option<String>,
pub tooltip: Option<String>,
pub max_damage: u32,
pub fire_resistant: bool,
pub fuel_ticks: u32,
pub food: Option<FoodDef>,
}
impl ItemDef {
pub fn new(id: impl Into<String>) -> Self {
Self {
id: id.into(),
max_stack: 64,
name: None,
tooltip: None,
max_damage: 0,
fire_resistant: false,
fuel_ticks: 0,
food: None,
}
}
pub fn max_stack(mut self, n: u8) -> Self {
self.max_stack = n;
self
}
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn tooltip(mut self, tooltip: impl Into<String>) -> Self {
self.tooltip = Some(tooltip.into());
self
}
pub fn max_damage(mut self, durability: u32) -> Self {
self.max_damage = durability;
self
}
pub fn fire_resistant(mut self) -> Self {
self.fire_resistant = true;
self
}
pub fn fuel(mut self, ticks: u32) -> Self {
self.fuel_ticks = ticks;
self
}
pub fn food(mut self, food: FoodDef) -> Self {
self.food = Some(food);
self
}
}
#[derive(Debug, Clone)]
pub struct ShapedRecipe {
pub id: String,
pub output: String,
pub count: u32,
rows: Vec<String>,
keys: Vec<(char, String)>,
}
impl ShapedRecipe {
pub fn new(id: impl Into<String>, output: impl Into<String>, count: u32) -> Self {
Self { id: id.into(), output: output.into(), count, rows: Vec::new(), keys: Vec::new() }
}
pub fn row(mut self, pattern: impl Into<String>) -> Self {
self.rows.push(pattern.into());
self
}
pub fn key(mut self, symbol: char, item_id: impl Into<String>) -> Self {
self.keys.push((symbol, item_id.into()));
self
}
pub fn to_json(&self) -> String {
let pattern: String = self.rows.iter()
.map(|r| format!("\"{}\"", r))
.collect::<Vec<_>>()
.join(",");
let keys: String = self.keys.iter()
.map(|(ch, item)| format!("\"{}\":{{\"item\":\"{}\"}}", ch, item))
.collect::<Vec<_>>()
.join(",");
format!(
"{{\"type\":\"minecraft:crafting_shaped\",\"pattern\":[{}],\"key\":{{{}}},\"result\":{{\"item\":\"{}\",\"count\":{}}}}}",
pattern, keys, self.output, self.count
)
}
pub fn ns_name(&self) -> (&str, &str) {
self.id.split_once(':').unwrap_or(("minecraft", &self.id))
}
}
#[derive(Debug, Clone)]
pub struct ShapelessRecipe {
pub id: String,
pub output: String,
pub count: u32,
pub ingredients: Vec<String>,
}
impl ShapelessRecipe {
pub fn new(id: impl Into<String>, output: impl Into<String>, count: u32) -> Self {
Self { id: id.into(), output: output.into(), count, ingredients: Vec::new() }
}
pub fn ingredient(mut self, item_id: impl Into<String>) -> Self {
self.ingredients.push(item_id.into());
self
}
pub fn to_json(&self) -> String {
let ingr: String = self.ingredients.iter()
.map(|i| format!("{{\"item\":\"{}\"}}", i))
.collect::<Vec<_>>()
.join(",");
format!(
"{{\"type\":\"minecraft:crafting_shapeless\",\"ingredients\":[{}],\"result\":{{\"item\":\"{}\",\"count\":{}}}}}",
ingr, self.output, self.count
)
}
pub fn ns_name(&self) -> (&str, &str) {
self.id.split_once(':').unwrap_or(("minecraft", &self.id))
}
}
#[derive(Debug, Clone)]
pub struct FurnaceRecipe {
pub id: String,
pub input: String,
pub output: String,
pub count: u32,
pub experience: f32,
pub cook_time: u32,
}
impl FurnaceRecipe {
pub fn new(
id: impl Into<String>,
input: impl Into<String>,
output: impl Into<String>,
count: u32,
) -> Self {
Self { id: id.into(), input: input.into(), output: output.into(), count, experience: 0.1, cook_time: 200 }
}
pub fn experience(mut self, xp: f32) -> Self {
self.experience = xp;
self
}
pub fn cook_time(mut self, ticks: u32) -> Self {
self.cook_time = ticks;
self
}
pub fn to_json(&self) -> String {
format!(
"{{\"type\":\"minecraft:smelting\",\"ingredient\":{{\"item\":\"{}\"}},\"result\":\"{}\",\"experience\":{},\"cookingtime\":{}}}",
self.input, self.output, self.experience, self.cook_time
)
}
pub fn ns_name(&self) -> (&str, &str) {
self.id.split_once(':').unwrap_or(("minecraft", &self.id))
}
}
#[derive(Debug, Clone)]
pub struct BookRecipe {
pub id: String,
pub book: String,
pub ingredients: Vec<String>,
}
impl BookRecipe {
pub fn new(id: impl Into<String>, book: impl Into<String>) -> Self {
Self { id: id.into(), book: book.into(), ingredients: Vec::new() }
}
pub fn ingredient(mut self, item_id: impl Into<String>) -> Self {
self.ingredients.push(item_id.into());
self
}
pub fn to_json(&self) -> String {
let ingr: String = self.ingredients.iter()
.map(|i| format!("{{\"item\":\"{}\"}}", i))
.collect::<Vec<_>>()
.join(",");
format!(
"{{\"type\":\"yog:crafting_book\",\"ingredients\":[{}],\"book\":\"{}\"}}",
ingr, self.book
)
}
pub fn ns_name(&self) -> (&str, &str) {
self.id.split_once(':').unwrap_or(("yog", &self.id))
}
}
#[derive(Debug, Clone)]
pub struct ItemModifier {
pub id: String,
pub function: String,
pub parameters: std::collections::HashMap<String, String>,
}
impl ItemModifier {
pub fn new(id: impl Into<String>, function: impl Into<String>) -> Self {
Self { id: id.into(), function: function.into(), parameters: std::collections::HashMap::new() }
}
pub fn param(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.parameters.insert(key.into(), value.into());
self
}
pub fn to_json(&self) -> String {
let params: String = self.parameters.iter()
.map(|(k, v)| format!("\"{}\":{}", k, v))
.collect::<Vec<_>>()
.join(",");
format!(
"{{\"function\":\"{}\",{}}}",
self.function, if params.is_empty() { String::new() } else { params }
)
}
}
#[derive(Debug, Clone)]
pub struct StartupGrant {
pub id: String,
pub items: Vec<String>,
pub book: Option<String>,
pub command: Option<String>,
}
impl StartupGrant {
pub fn new(id: impl Into<String>) -> Self {
Self { id: id.into(), items: Vec::new(), book: None, command: None }
}
pub fn item(mut self, item_id: impl Into<String>) -> Self {
self.items.push(item_id.into());
self
}
pub fn book(mut self, book: impl Into<String>) -> Self {
self.book = Some(book.into());
self
}
pub fn command(mut self, cmd: impl Into<String>) -> Self {
self.command = Some(cmd.into());
self
}
pub fn to_json(&self) -> String {
let items: Vec<String> = self.items.iter().map(|i| format!("{{\"item\":\"{}\"}}", i)).collect();
let mut entries = String::new();
if !items.is_empty() {
entries.push_str(&format!("[{}]", items.join(",")));
}
if let Some(book) = &self.book {
if !entries.is_empty() {
entries.push(',');
}
let book_entry = format!(
"{{\"type\":\"item\",\"name\":\"minecraft:written_book\",\"functions\":[{{\"function\":\"set_nbt\",\"tag\":\"{{yog_book:\\\"{}\\\"}}\"}}]}}",
book
);
entries.push_str(&book_entry);
}
if let Some(cmd) = &self.command {
if !entries.is_empty() {
entries.push(',');
}
entries.push_str(&format!(
"{{\"type\":\"minecraft:command\",\"command\":\"{}\"}}",
cmd.replace('"', "\\\"")
));
}
format!(
"{{\"type\":\"yog:startup_grant\",\"entries\":{},\"id\":\"{}\"}}",
if entries.is_empty() { "[]".to_string() } else { entries },
self.id
)
}
}
#[derive(Debug, Clone)]
pub struct AdvancementReward {
pub id: String,
pub item: String,
pub nbt: Option<String>,
pub book: Option<String>,
}
impl AdvancementReward {
pub fn new(id: impl Into<String>) -> Self {
Self { id: id.into(), item: "minecraft:written_book".into(), nbt: None, book: None }
}
pub fn item(mut self, item: impl Into<String>) -> Self {
self.item = item.into();
self
}
pub fn nbt(mut self, nbt: impl Into<String>) -> Self {
self.nbt = Some(nbt.into());
self
}
pub fn book(mut self, book: impl Into<String>) -> Self {
let book_str: String = book.into();
self.book = Some(book_str.clone());
self.nbt = Some(format!("{{yog_book:\"{}\",title:\"Yog Book\",author:\"Yog\"}}", book_str));
self
}
pub fn to_json(&self) -> String {
let nbt_part = self.nbt.as_ref().map(|n| format!("{{\"function\":\"set_nbt\",\"tag\":{}}}", n));
let entries = if let Some(nbt_part) = nbt_part {
format!("[{{\"type\":\"item\",\"name\":\"{}\",\"functions\":[{}]}}]", self.item, nbt_part)
} else {
format!("[{{\"type\":\"item\",\"name\":\"{}\"}}]", self.item)
};
format!(
"{{\"type\":\"advancement_reward\",\"pools\":[{{\"rolls\":1,\"entries\":{}}}]}}",
entries
)
}
}
#[derive(Debug, Clone)]
pub struct BlockDef {
pub id: String,
pub hardness: f32,
pub resistance: f32,
pub name: Option<String>,
pub shape: Option<[f32; 6]>,
pub light_level: u8,
pub sound: Option<String>,
pub requires_tool: bool,
pub no_collision: bool,
pub slipperiness: f32,
}
impl BlockDef {
pub fn new(id: impl Into<String>) -> Self {
Self {
id: id.into(),
hardness: 1.5,
resistance: 6.0,
name: None,
shape: None,
light_level: 0,
sound: None,
requires_tool: false,
no_collision: false,
slipperiness: 0.0,
}
}
pub fn strength(mut self, hardness: f32, resistance: f32) -> Self {
self.hardness = hardness;
self.resistance = resistance;
self
}
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn shape(mut self, x1: f32, y1: f32, z1: f32, x2: f32, y2: f32, z2: f32) -> Self {
self.shape = Some([x1, y1, z1, x2, y2, z2]);
self
}
pub fn light_level(mut self, level: u8) -> Self {
self.light_level = level.min(15);
self
}
pub fn sound(mut self, group: impl Into<String>) -> Self {
self.sound = Some(group.into());
self
}
pub fn requires_tool(mut self) -> Self {
self.requires_tool = true;
self
}
pub fn no_collision(mut self) -> Self {
self.no_collision = true;
self
}
pub fn slipperiness(mut self, value: f32) -> Self {
self.slipperiness = value;
self
}
}