implement registering scoreboards in datapack for automatic creation and deletion
This commit is contained in:
parent
46499b6abe
commit
9337d09d7b
|
@ -3,7 +3,7 @@ on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- development
|
- develop
|
||||||
- 'releases/**'
|
- 'releases/**'
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ use shulkerbox::{
|
||||||
util::compile::CompileOptions,
|
util::compile::CompileOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dp = Datapack::new("shulkerpack", 20) // Create a new datapack with the name "shulkerpack" and the pack format 20
|
let mut dp = Datapack::new("shulker", 20) // Create a new datapack with the name "shulkerpack" and the pack format 20
|
||||||
.with_description("I created this datapack with rust") // Add a description to the datapack
|
.with_description("I created this datapack with rust") // Add a description to the datapack
|
||||||
.with_supported_formats(16..=20) // Add the supported formats of the datapack
|
.with_supported_formats(16..=20) // Add the supported formats of the datapack
|
||||||
.with_template_folder(Path::new("./template")) // Add a template folder to the datapack. This will include all files in the template folder in the root of the datapack and can be used for including the "pack.png" file
|
.with_template_folder(Path::new("./template")) // Add a template folder to the datapack. This will include all files in the template folder in the root of the datapack and can be used for including the "pack.png" file
|
||||||
|
|
|
@ -5,10 +5,12 @@ use shulkerbox::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// create a new datapack
|
// create a new datapack
|
||||||
let mut dp = Datapack::new(16).with_supported_formats(16..=20);
|
let mut dp = Datapack::new("example", 16).with_supported_formats(16..=20);
|
||||||
|
|
||||||
// get the namespace "test"
|
dp.register_scoreboard("example_scoreboard", Some("dummy"), None);
|
||||||
let namespace = dp.namespace_mut("test");
|
|
||||||
|
// get the namespace "example"
|
||||||
|
let namespace = dp.namespace_mut("example");
|
||||||
|
|
||||||
// get the function "foo" of the namespace "test" and add some commands
|
// get the function "foo" of the namespace "test" and add some commands
|
||||||
let foo_function = namespace.function_mut("foo");
|
let foo_function = namespace.function_mut("foo");
|
||||||
|
@ -32,7 +34,7 @@ fn main() {
|
||||||
)),
|
)),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
dp.add_load("test:foo");
|
dp.add_load("example:foo");
|
||||||
|
|
||||||
// compile the datapack
|
// compile the datapack
|
||||||
let v_folder = dp.compile(&CompileOptions::default());
|
let v_folder = dp.compile(&CompileOptions::default());
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub use command::{Command, Condition, Execute};
|
||||||
pub use function::Function;
|
pub use function::Function;
|
||||||
pub use namespace::Namespace;
|
pub use namespace::Namespace;
|
||||||
|
|
||||||
use std::{collections::HashMap, ops::RangeInclusive, sync::Mutex};
|
use std::{borrow::Cow, collections::BTreeMap, ops::RangeInclusive, sync::Mutex};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
util::compile::{CompileOptions, CompilerState, MutCompilerState},
|
util::compile::{CompileOptions, CompilerState, MutCompilerState},
|
||||||
|
@ -23,7 +23,10 @@ pub struct Datapack {
|
||||||
description: String,
|
description: String,
|
||||||
pack_format: u8,
|
pack_format: u8,
|
||||||
supported_formats: Option<RangeInclusive<u8>>,
|
supported_formats: Option<RangeInclusive<u8>>,
|
||||||
namespaces: HashMap<String, Namespace>,
|
main_namespace_name: String,
|
||||||
|
namespaces: BTreeMap<String, Namespace>,
|
||||||
|
/// Scoreboard name -> (criteria, display name)
|
||||||
|
scoreboards: BTreeMap<String, (Option<String>, Option<String>)>,
|
||||||
custom_files: VFolder,
|
custom_files: VFolder,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,12 +35,14 @@ impl Datapack {
|
||||||
|
|
||||||
/// Create a new Minecraft datapack.
|
/// Create a new Minecraft datapack.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(pack_format: u8) -> Self {
|
pub fn new(main_namespace_name: impl Into<String>, pack_format: u8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
description: String::from("A Minecraft datapack created with shulkerbox"),
|
description: String::from("A Minecraft datapack created with shulkerbox"),
|
||||||
pack_format,
|
pack_format,
|
||||||
supported_formats: None,
|
supported_formats: None,
|
||||||
namespaces: HashMap::new(),
|
main_namespace_name: main_namespace_name.into(),
|
||||||
|
namespaces: BTreeMap::new(),
|
||||||
|
scoreboards: BTreeMap::new(),
|
||||||
custom_files: VFolder::new(),
|
custom_files: VFolder::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,6 +115,19 @@ impl Datapack {
|
||||||
.add_value(tag::TagValue::Simple(function.to_string()));
|
.add_value(tag::TagValue::Simple(function.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Register a scoreboard.
|
||||||
|
pub fn register_scoreboard(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
criteria: Option<&str>,
|
||||||
|
display_name: Option<&str>,
|
||||||
|
) {
|
||||||
|
self.scoreboards.insert(
|
||||||
|
name.to_string(),
|
||||||
|
(criteria.map(String::from), display_name.map(String::from)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a custom file to the datapack.
|
/// Add a custom file to the datapack.
|
||||||
pub fn add_custom_file(&mut self, path: &str, file: VFile) {
|
pub fn add_custom_file(&mut self, path: &str, file: VFile) {
|
||||||
self.custom_files.add_file(path, file);
|
self.custom_files.add_file(path, file);
|
||||||
|
@ -132,8 +150,62 @@ impl Datapack {
|
||||||
root_folder.add_file("pack.mcmeta", mcmeta);
|
root_folder.add_file("pack.mcmeta", mcmeta);
|
||||||
let mut data_folder = VFolder::new();
|
let mut data_folder = VFolder::new();
|
||||||
|
|
||||||
|
let mut modified_namespaces = self
|
||||||
|
.namespaces
|
||||||
|
.iter()
|
||||||
|
.map(|(name, namespace)| (name.as_str(), Cow::Borrowed(namespace)))
|
||||||
|
.collect::<BTreeMap<_, _>>();
|
||||||
|
|
||||||
|
let mut uninstall_commands = options.uninstall_function.then(Vec::new);
|
||||||
|
|
||||||
|
if !self.scoreboards.is_empty() {
|
||||||
|
let main_namespace = modified_namespaces
|
||||||
|
.entry(&self.main_namespace_name)
|
||||||
|
.or_insert_with(|| Cow::Owned(Namespace::new(&self.main_namespace_name)));
|
||||||
|
let register_scoreboard_function = main_namespace
|
||||||
|
.to_mut()
|
||||||
|
.function_mut("shu/register_scoreboards");
|
||||||
|
for (name, (criteria, display_name)) in &self.scoreboards {
|
||||||
|
let mut creation_command = format!(
|
||||||
|
"scoreboard objectives add {name} {criteria}",
|
||||||
|
criteria = criteria.as_deref().unwrap_or("dummy")
|
||||||
|
);
|
||||||
|
if let Some(display_name) = display_name {
|
||||||
|
creation_command.push(' ');
|
||||||
|
creation_command.push_str(display_name);
|
||||||
|
}
|
||||||
|
register_scoreboard_function.add_command(Command::Raw(creation_command));
|
||||||
|
|
||||||
|
if let Some(uninstall_commands) = uninstall_commands.as_mut() {
|
||||||
|
uninstall_commands
|
||||||
|
.push(Command::Raw(format!("scoreboard objectives remove {name}")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let minecraft_namespace = modified_namespaces
|
||||||
|
.entry("minecraft")
|
||||||
|
.or_insert_with(|| Cow::Owned(Namespace::new("minecraft")));
|
||||||
|
minecraft_namespace
|
||||||
|
.to_mut()
|
||||||
|
.tag_mut("load", tag::TagType::Function)
|
||||||
|
.add_value(tag::TagValue::Simple(format!(
|
||||||
|
"{}:shu/register_scoreboards",
|
||||||
|
self.main_namespace_name
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(uninstall_commands) = uninstall_commands {
|
||||||
|
let main_namespace = modified_namespaces
|
||||||
|
.entry(&self.main_namespace_name)
|
||||||
|
.or_insert_with(|| Cow::Owned(Namespace::new(&self.main_namespace_name)));
|
||||||
|
let uninstall_function = main_namespace.to_mut().function_mut("uninstall");
|
||||||
|
uninstall_function
|
||||||
|
.get_commands_mut()
|
||||||
|
.extend(uninstall_commands);
|
||||||
|
}
|
||||||
|
|
||||||
// Compile namespaces
|
// Compile namespaces
|
||||||
for (name, namespace) in &self.namespaces {
|
for (name, namespace) in modified_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);
|
data_folder.add_existing_folder(name, namespace_folder);
|
||||||
}
|
}
|
||||||
|
@ -180,7 +252,7 @@ mod tests {
|
||||||
fn test_datapack() {
|
fn test_datapack() {
|
||||||
let template_dir = tempfile::tempdir().expect("error creating tempdir");
|
let template_dir = tempfile::tempdir().expect("error creating tempdir");
|
||||||
|
|
||||||
let mut dp = Datapack::new(Datapack::LATEST_FORMAT)
|
let mut dp = Datapack::new("main", Datapack::LATEST_FORMAT)
|
||||||
.with_description("My datapack")
|
.with_description("My datapack")
|
||||||
.with_template_folder(template_dir.path())
|
.with_template_folder(template_dir.path())
|
||||||
.expect("error reading template folder");
|
.expect("error reading template folder");
|
||||||
|
@ -193,7 +265,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_generate_mcmeta() {
|
fn test_generate_mcmeta() {
|
||||||
let dp = &Datapack::new(Datapack::LATEST_FORMAT).with_description("foo");
|
let dp = &Datapack::new("main", Datapack::LATEST_FORMAT).with_description("foo");
|
||||||
let state = Mutex::new(CompilerState::default());
|
let state = Mutex::new(CompilerState::default());
|
||||||
let mcmeta = generate_mcmeta(dp, &CompileOptions::default(), &state);
|
let mcmeta = generate_mcmeta(dp, &CompileOptions::default(), &state);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ pub struct CompileOptions {
|
||||||
pub(crate) pack_format: u8,
|
pub(crate) pack_format: u8,
|
||||||
/// Whether to compile in debug mode.
|
/// Whether to compile in debug mode.
|
||||||
pub(crate) debug: bool,
|
pub(crate) debug: bool,
|
||||||
|
/// Whether to generate an uninstall function.
|
||||||
|
pub(crate) uninstall_function: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompileOptions {
|
impl CompileOptions {
|
||||||
|
@ -25,6 +27,15 @@ impl CompileOptions {
|
||||||
pub fn with_debug(self, debug: bool) -> Self {
|
pub fn with_debug(self, debug: bool) -> Self {
|
||||||
Self { debug, ..self }
|
Self { debug, ..self }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set whether to generate an uninstall function.
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_uninstall_function(self, uninstall_function: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
uninstall_function,
|
||||||
|
..self
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CompileOptions {
|
impl Default for CompileOptions {
|
||||||
|
@ -32,6 +43,7 @@ impl Default for CompileOptions {
|
||||||
Self {
|
Self {
|
||||||
pack_format: Datapack::LATEST_FORMAT,
|
pack_format: Datapack::LATEST_FORMAT,
|
||||||
debug: true,
|
debug: true,
|
||||||
|
uninstall_function: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue