@throw-out-error/minecraft-datapack
Version:
A module for making minecraft datapacks with node to cut down on the repetition.
175 lines (174 loc) • 6.84 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Namespace = void 0;
const path_1 = __importDefault(require("path"));
const utility_1 = require("./utility");
const tag_1 = require("./tag");
const recipes_1 = require("./recipes");
const loot_1 = require("./loot");
const minecraft_mcfunction_1 = require("@throw-out-error/minecraft-mcfunction");
const dataCategories = [
"functions",
"tags/blocks",
"tags/items",
"tags/functions",
"recipes",
"loot_tables",
"predicates"
];
class Namespace {
/**
* Creates a namespace
* @param {string} name The name of the namespace
*/
constructor(name) {
if (utility_1.hasIllegalChars(name))
throw new Error("Namespace names can only contain the following characters 0-9, a-z, _, -, .");
if (name == "minecraft")
throw new Error("The Datapack class creates the minecraft namespace by default, datapack.minecraft, adding it a second time will cause it to be overridden");
/** @type {string} the name of the namespace */
this.name = name;
/** @type {object} the dictionary of block tag files */
this.blockTags = {};
/** @type {object} the dictionary of item tag files */
this.itemTags = {};
/** @type {object} the dictionary of function tag files */
this.functionTags = {};
/** @type {object} the dictionary of recipe files */
this.recipes = {};
/** @type {object} the dictionary of loot table files */
this.lootTables = {};
/** @type {object} the dictionary of mcfunction files */
this.functions = {};
}
/**
* Outputs the namespace's files
* @param {string} root The root path where the namespace will compile
*/
async compile(root) {
const namespacePath = path_1.default.join(root, "data", this.name);
utility_1.mkdirIfNotExist(namespacePath);
dataCategories.forEach(category => {
utility_1.mkdirIfNotExist(path_1.default.join(namespacePath, category));
});
const compiling = [];
const tagsPath = path_1.default.join(namespacePath, "tags");
["block", "item", "function"].forEach(type => {
const tags = this[type + "Tags"];
for (let tag of Object.values(tags)) {
compiling.push(tag.compile(tagsPath));
}
});
const recipePath = path_1.default.join(namespacePath, "recipes");
for (let recipe of Object.values(this.recipes)) {
compiling.push(recipe.compile(recipePath));
}
const tablePath = path_1.default.join(namespacePath, "loot_tables");
for (let table of Object.values(this.lootTables)) {
compiling.push(table.compile(tablePath));
}
const functionPath = path_1.default.join(namespacePath, "functions");
for (let funct of Object.values(this.functions)) {
compiling.push(funct.compile(functionPath));
}
return Promise.all(compiling);
}
/**
* Add a tag to the namespace
* @param {Tag} tag The tag to be added
* @returns {Tag} a reference to the added tag
*/
addTag(tag) {
if (Object.prototype.hasOwnProperty.call(this[`${tag.type}Tags`], tag.path))
throw new Error(`The tag ${tag.type}/${tag.path} has already been added to this namespace`);
let copy = tag_1.Tag.copy(tag);
this[`${tag.type}Tags`][tag.path] = copy;
return copy;
}
/**
* Create a tag and add it to the namespace
* @param {string} path The path of the tag file relative to namespace/tags/type (excluding the file extension)
* @param {('block'|'item'|'function')} type The type of tag
* @param {string[]} [values=[]]
* @returns {Tag} a reference to the created tag
*/
createTag(path, type, values) {
let tag = new tag_1.Tag(path, type, values || []);
this.addTag(tag);
return tag;
}
/**
* Delete a tag
* @param {string} path The path of the tag file relative to namespace/tags/type (excluding the file extension) to be deleted
* @param {('block'|'item'|'function')} type The type of tag to be deleted
*/
deleteTag(path, type) {
delete this[`${type}Tags`][path];
}
/**
* Add a recipe to the namespace
* @param {Recipe} recipe The recipe to be added
* @returns {Recipe} a reference to the added recipe
*/
addRecipe(recipe) {
if (Object.prototype.hasOwnProperty.call(this.recipes, recipe.path))
throw new Error(`The recipe ${recipe.path} has already been added to this namespace`);
let copy = recipes_1.Recipe.copy(recipe);
this.recipes[recipe.path] = copy;
return copy;
}
/**
* Delete a recipe
* @param {string} path The path of the recipe file relative to namespace/recipes (excluding the file extension) to be deleted
*/
deleteRecipe(path) {
delete this.recipes[path];
}
/**
* Add a loot table to the namespace
* @param {LootTable} lootTable The loot table to be added
* @returns {LootTable} a reference to the added loot table
*/
addLootTable(lootTable) {
if (Object.prototype.hasOwnProperty.call(this.lootTables, lootTable.path))
throw new Error(`This name space already has the loot table ${lootTable.path}`);
let copy = loot_1.LootTable.copy(lootTable);
this.lootTables[lootTable.path] = copy;
return copy;
}
/**
* Create a loot table then add it to the namespace
* @param {string} path the path of the loot table to be created
* @returns {LootTable} a reference to the created pool
*/
createLootTable(path) {
let lootTable = new loot_1.LootTable(path);
this.addLootTable(lootTable);
return lootTable;
}
addFunction(functOrSource) {
if (typeof functOrSource === "function") {
functOrSource = new minecraft_mcfunction_1.McFunction(functOrSource);
}
if (this.functions[functOrSource.name]) {
throw Error("Duplicate function name");
}
this.functions[functOrSource.name] = functOrSource;
return functOrSource;
}
/**
* Creates a copy of the namespace
* @param {Namespace} namespace the namespace to be copied
* @returns {Namespace} a copy of the namespace
*/
static copy(namespace) {
let copy = new Namespace("_");
for (let key in { ...namespace })
copy[key] = namespace[key];
return copy;
}
}
exports.Namespace = Namespace;