diff --git a/src/datapack/mod.rs b/src/datapack/mod.rs index 74e4865..db19eea 100644 --- a/src/datapack/mod.rs +++ b/src/datapack/mod.rs @@ -90,14 +90,14 @@ impl Datapack { /// Add a function to the tick function list. pub fn add_tick(&mut self, function: &str) { self.namespace_mut("minecraft") - .tag_mut("tick", tag::TagType::Functions) + .tag_mut("tick", tag::TagType::Function) .add_value(tag::TagValue::Simple(function.to_string())); } /// Add a function to the load function list. pub fn add_load(&mut self, function: &str) { self.namespace_mut("minecraft") - .tag_mut("load", tag::TagType::Functions) + .tag_mut("load", tag::TagType::Function) .add_value(tag::TagValue::Simple(function.to_string())); } @@ -111,17 +111,21 @@ impl Datapack { #[tracing::instrument(level = "debug", skip(self))] pub fn compile(&self, options: &CompileOptions) -> VFolder { tracing::debug!("Compiling datapack: {:?}", self); + let options = CompileOptions { + pack_format: self.pack_format, + ..options.clone() + }; let compiler_state = Mutex::new(CompilerState::default()); let mut root_folder = self.custom_files.clone(); - let mcmeta = generate_mcmeta(self, options, &compiler_state); + let mcmeta = generate_mcmeta(self, &options, &compiler_state); root_folder.add_file("pack.mcmeta", mcmeta); let mut data_folder = VFolder::new(); // Compile namespaces for (name, namespace) in &self.namespaces { - let namespace_folder = namespace.compile(options, &compiler_state); + let namespace_folder = namespace.compile(&options, &compiler_state); data_folder.add_existing_folder(name, namespace_folder); } diff --git a/src/datapack/namespace.rs b/src/datapack/namespace.rs index f1f2ab9..99f53c3 100644 --- a/src/datapack/namespace.rs +++ b/src/datapack/namespace.rs @@ -3,7 +3,7 @@ use crate::{ util::{ compile::{CompileOptions, FunctionCompilerState, MutCompilerState}, - ExtendableQueue, + pack_format, ExtendableQueue, }, virtual_fs::VFolder, }; @@ -101,7 +101,10 @@ impl Namespace { while let Some((path, function)) = functions.next() { let function_state = FunctionCompilerState::new(&path, &self.name, functions.clone()); root_folder.add_file( - &format!("function/{path}.mcfunction"), + &format!( + "{directory_name}/{path}.mcfunction", + directory_name = pack_format::function_directory_name(options.pack_format) + ), function.compile(options, state, &function_state), ); } @@ -109,7 +112,13 @@ impl Namespace { // compile tags for ((path, tag_type), tag) in &self.tags { let vfile = tag.compile(options, state); - root_folder.add_file(&format!("tags/{tag_type}/{path}.json"), vfile); + root_folder.add_file( + &format!( + "tags/{tag_directory}/{path}.json", + tag_directory = tag_type.get_directory_name(options.pack_format) + ), + vfile, + ); } root_folder diff --git a/src/datapack/tag.rs b/src/datapack/tag.rs index 7aebde5..ee95cdd 100644 --- a/src/datapack/tag.rs +++ b/src/datapack/tag.rs @@ -68,31 +68,65 @@ impl Tag { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TagType { /// A tag for blocks. - Blocks, + Block, /// A tag for fluids. - Fluids, + Fluid, /// A tag for items. - Items, + Item, /// A tag for entities. - Entities, + Entity, /// A tag for game events. - GameEvents, + GameEvent, /// A tag for functions. - Functions, - /// A custom tag - /// `Others()` => `data//tags/` - Others(String), + Function, + /// A custom tag type. + /// `Other()` => `data//tags/` + Other(String), } + +impl TagType { + #[must_use] + pub fn get_directory_name(&self, pack_format: u8) -> &str { + if pack_format < 43 { + match self { + Self::Block => "blocks", + Self::Fluid => "fluids", + Self::Item => "items", + Self::Entity => "entity_types", + Self::GameEvent => "game_events", + Self::Function => "functions", + Self::Other(path) => path, + } + } else { + match self { + Self::Block => "block", + Self::Fluid => "fluid", + Self::Item => "item", + Self::Entity => "entity_type", + Self::GameEvent => "game_event", + Self::Function => { + if pack_format < 45 { + "functions" + } else { + "function" + } + } + Self::Other(path) => path, + } + } + } +} + impl Display for TagType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let str = match self { - Self::Blocks => "block".to_string(), - Self::Fluids => "fluid".to_string(), - Self::Items => "item".to_string(), - Self::Entities => "entity_type".to_string(), - Self::GameEvents => "game_event".to_string(), - Self::Functions => "function".to_string(), - Self::Others(path) => path.to_string(), + Self::Block => "block".to_string(), + Self::Fluid => "fluid".to_string(), + Self::Item => "item".to_string(), + Self::Entity => "entity_type".to_string(), + Self::GameEvent => "game_event".to_string(), + Self::Function => "function".to_string(), + Self::Other(path) => path.to_string(), }; f.write_str(&str) } diff --git a/src/util/compile.rs b/src/util/compile.rs index 4c52632..cc6927a 100644 --- a/src/util/compile.rs +++ b/src/util/compile.rs @@ -4,7 +4,7 @@ use std::sync::Mutex; use getset::Getters; -use crate::datapack::Function; +use crate::datapack::{Datapack, Function}; use super::extendable_queue::ExtendableQueue; @@ -13,6 +13,8 @@ use super::extendable_queue::ExtendableQueue; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone)] pub struct CompileOptions { + /// The pack format of the target datapack. + pub(crate) pack_format: u8, /// Whether to compile in debug mode. pub(crate) debug: bool, } @@ -21,13 +23,16 @@ impl CompileOptions { /// Set whether to compile in debug mode. #[must_use] pub fn with_debug(self, debug: bool) -> Self { - Self { debug } + Self { debug, ..self } } } impl Default for CompileOptions { fn default() -> Self { - Self { debug: true } + Self { + pack_format: Datapack::LATEST_FORMAT, + debug: true, + } } } diff --git a/src/util/mod.rs b/src/util/mod.rs index 78121e0..f8757c7 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -2,6 +2,7 @@ pub mod compile; mod extendable_queue; +pub(crate) mod pack_format; #[doc(inline)] pub use extendable_queue::ExtendableQueue; diff --git a/src/util/pack_format.rs b/src/util/pack_format.rs new file mode 100644 index 0000000..43321c5 --- /dev/null +++ b/src/util/pack_format.rs @@ -0,0 +1,9 @@ +/// Get the name of the function directory depending on the pack format. +#[must_use] +pub const fn function_directory_name(pack_format: u8) -> &'static str { + if pack_format < 45 { + "functions" + } else { + "function" + } +}