bedrock-development
Version:
APIs for creating and editing files related to Minecraft Bedrock development.
275 lines (274 loc) • 20.4 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var _a;
import { Option } from "commander";
import { ClientItemTexture, ServerItem, LangFile, ClientAnimationController, ClientAnimation, ClientAttachable, ClientGeometryAttachable, ClientAttachableArmorHelmet, ClientGeometryArmor, ClientAttachableArmorBoots, ClientAttachableArmorLeggings, ClientAttachableArmorChestplate } from "../../types/index.js";
import { Directories, copySourceFile, setFiles } from "../../file_manager.js";
import { NameData, currentFormatVersion, implementConfig } from "../../utils.js";
import { CommandMap } from "../command_map.js";
var ServerItemOptions;
(function (ServerItemOptions) {
ServerItemOptions["basic"] = "basic";
ServerItemOptions["attachable"] = "attachable";
ServerItemOptions["food"] = "food";
ServerItemOptions["armor_set"] = "armor_set";
ServerItemOptions["helmet"] = "helmet";
ServerItemOptions["chestplate"] = "chestplate";
ServerItemOptions["leggings"] = "leggings";
ServerItemOptions["boots"] = "boots";
})(ServerItemOptions || (ServerItemOptions = {}));
;
CommandMap.addCommand("root.new.item", {
parent: (_a = CommandMap.getCommandEntry("root.new")) === null || _a === void 0 ? void 0 : _a.command,
commandOptions(command) {
command
.name("item")
.description("creates new bedrock items")
.argument("<names...>", 'item names as "namespace:item"')
.option("--no-lang", "do not add lang file")
.addOption(new Option("-s, --stack <stack_size>", "max stack size").default(64).argParser(parseInt))
.option("-c, --cooldown <cooldown_duration>", "cooldown duration")
.option("-o, --override", "override existing files")
.addOption(new Option("-t, --type <item_type>", "item type").choices(Object.keys(ServerItemOptions)).default("basic"));
},
commandAction: triggerCreateNewItem,
});
function triggerCreateNewItem(names, options) {
return __awaiter(this, void 0, void 0, function* () {
implementConfig();
names.forEach((name) => {
const nameData = new NameData(name);
const files = createFileTemplates[options.type](nameData, options);
if ([ServerItemOptions.armor_set, ServerItemOptions.helmet, ServerItemOptions.chestplate, ServerItemOptions.leggings, ServerItemOptions.boots].some(itemType => itemType === options.type)) {
files.push(ClientGeometryArmor.createFromTemplate(nameData).toFile());
copySourceFile('images/armor_uv_texture.png', Directories.RESOURCE_PATH + 'textures/' + Directories.ADDON_PATH + 'models/armor/' + nameData.directory + nameData.shortname + '.png');
}
if (options.override)
files.forEach(file => file.handleExisting = "overwrite");
setFiles(files);
});
});
}
const createFileTemplates = {
basic: function (nameData, options) {
const item = ServerItem.createFromTemplate(nameData);
item.setDisplayData(nameData);
item.setStackSize(options.stack);
if (options.cooldown)
item.setCooldown(options.cooldown);
const files = [item.toFile()];
if (options.lang) {
files.push(...LangFile.addToAllLangs('item names', `item.${nameData.fullname}.name=${nameData.display}`).files);
}
copySourceFile('images/sprite.png', Directories.RESOURCE_PATH + 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + '.png');
files.push(ClientItemTexture.fileWithAddedTextures({ name: nameData.shortname, texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname }));
return files;
},
boots: function (nameData, options) {
const item = ServerItem.createFromTemplate(nameData);
item.setDisplayData(nameData);
item.setStackSize(1);
if (options.cooldown)
item.setCooldown(options.cooldown);
item.setWearable("slot.armor.feet", 3);
const files = [item.toFile()];
if (options.lang) {
files.push(...LangFile.addToAllLangs('item names', `item.${nameData.fullname}.name=${nameData.display}`).files);
}
files.push(ClientAttachableArmorBoots.createFromTemplate(nameData).toFile());
copySourceFile('images/sprite.png', Directories.RESOURCE_PATH + 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + '.png');
files.push(ClientItemTexture.fileWithAddedTextures({ name: nameData.shortname, texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname }));
return files;
},
leggings: function (nameData, options) {
const item = ServerItem.createFromTemplate(nameData);
item.setDisplayData(nameData);
item.setStackSize(1);
if (options.cooldown)
item.setCooldown(options.cooldown);
item.setWearable("slot.armor.legs", 6);
const files = [item.toFile()];
if (options.lang) {
files.push(...LangFile.addToAllLangs('item names', `item.${nameData.fullname}.name=${nameData.display}`).files);
}
files.push(ClientAttachableArmorLeggings.createFromTemplate(nameData).toFile());
copySourceFile('images/sprite.png', Directories.RESOURCE_PATH + 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + '.png');
files.push(ClientItemTexture.fileWithAddedTextures({ name: nameData.shortname, texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname }));
return files;
},
chestplate: function (nameData, options) {
const item = ServerItem.createFromTemplate(nameData);
item.setDisplayData(nameData);
item.setStackSize(1);
if (options.cooldown)
item.setCooldown(options.cooldown);
item.setWearable("slot.armor.chest", 8);
const files = [item.toFile()];
if (options.lang) {
files.push(...LangFile.addToAllLangs('item names', `item.${nameData.fullname}.name=${nameData.display}`).files);
}
files.push(ClientAttachableArmorChestplate.createFromTemplate(nameData).toFile());
copySourceFile('images/sprite.png', Directories.RESOURCE_PATH + 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + '.png');
files.push(ClientItemTexture.fileWithAddedTextures({ name: nameData.shortname, texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname }));
return files;
},
helmet: function (nameData, options) {
const item = ServerItem.createFromTemplate(nameData);
item.setDisplayData(nameData);
item.setStackSize(1);
if (options.cooldown)
item.setCooldown(options.cooldown);
item.setWearable("slot.armor.head", 3);
const files = [item.toFile()];
if (options.lang) {
files.push(...LangFile.addToAllLangs('item names', `item.${nameData.fullname}.name=${nameData.display}`).files);
}
files.push(ClientAttachableArmorHelmet.createFromTemplate(nameData).toFile());
copySourceFile('images/sprite.png', Directories.RESOURCE_PATH + 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + '.png');
files.push(ClientItemTexture.fileWithAddedTextures({ name: nameData.shortname, texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname }));
return files;
},
armor_set: function (nameData, options) {
const files = [];
const originalLang = options.lang;
options.lang = false;
files.push(...createFileTemplates.boots(new NameData(nameData.original + "_boots"), options));
files.push(...createFileTemplates.leggings(new NameData(nameData.original + "_leggings"), options));
files.push(...createFileTemplates.chestplate(new NameData(nameData.original + "_chestplate"), options));
files.push(...createFileTemplates.helmet(new NameData(nameData.original + "_helmet"), options));
if (originalLang) {
const lang = new LangFile('*.lang');
lang.addToCategory('item names', `item.${nameData.fullname}_boots.name=${nameData.display} Boots`, `item.${nameData.fullname}_leggings.name=${nameData.display} Leggings`, `item.${nameData.fullname}_chestplate.name=${nameData.display} Chestplate`, `item.${nameData.fullname}_helmet.name=${nameData.display} Helmet`);
files.push(...lang.files);
}
files.push(ClientItemTexture.fileWithAddedTextures({ name: nameData.shortname + "_boots", texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + "_boots" }, { name: nameData.shortname + "_leggings", texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + "_leggings" }, { name: nameData.shortname + "_chestplate", texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + "_chestplate" }, { name: nameData.shortname + "_helmet", texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + "_helmet" }));
return files;
},
attachable: function (nameData, options) {
const item = ServerItem.createFromTemplate(nameData);
item.setDisplayData(nameData);
item.setStackSize(options.stack);
if (options.cooldown)
item.setCooldown(options.cooldown);
item.setModifiers();
const files = [item.toFile()];
if (options.lang) {
const langs = new LangFile('*.lang');
langs.addToCategory('item names', `item.${nameData.fullname}.name=${nameData.display}`);
files.push(...langs.files);
}
copySourceFile('images/uv_medium_texture.png', Directories.RESOURCE_PATH + 'textures/' + Directories.ADDON_PATH + 'attachables/' + nameData.directory + nameData.shortname + '.png');
// animation controller
const controller = new ClientAnimationController(ClientAnimationController.createFilePath(nameData), {
format_version: currentFormatVersion,
animation_controllers: {
[`controller.animation.${nameData.namespace}.item.custom_items.${nameData.shortname}`]: {
initial_state: 'idle',
states: {
idle: {
animations: [
{
[`${nameData.shortname}.idle.first_person`]: "v.is_first_person"
},
{
[`${nameData.shortname}.idle.third_person`]: "!v.is_first_person"
}
],
transitions: [
{
attack: "query.is_using_item || query.is_name_any('§a§t§t§a§c§k§e§r')"
}
],
blend_transition: 0.2
},
attack: {
animations: [
{
[`${nameData.shortname}.attack.first_person`]: "v.is_first_person"
},
{
[`${nameData.shortname}.attack.third_person`]: "!v.is_first_person"
}
],
transitions: [
{
idle: "q.any_animation_finished && !query.is_using_item"
},
{
escape_attack: "q.any_animation_finished && query.is_using_item"
}
],
blend_transition: 0.2
},
escape_attack: {
animations: [
{
[`${nameData.shortname}.idle.first_person`]: "v.is_first_person"
},
{
[`${nameData.shortname}.idle.third_person`]: "!v.is_first_person"
}
],
transitions: [
{
idle: "!query.is_using_item"
}
],
blend_transition: 0.2
}
}
}
}
});
files.push(controller.toFile());
// animation
const animation = new ClientAnimation(ClientAnimation.createFilePath(nameData), {
format_version: currentFormatVersion,
animations: {
[`animation.${nameData.namespace}.${nameData.shortname}.blockbench_fix`]: { loop: true, bones: { root: { rotation: [0, 0, 0], position: [7, -15, 1] } } },
[`animation.${nameData.namespace}.player.${nameData.shortname}.idle.first_person`]: { loop: true, override_previous_animation: true, blend_weight: `v.is_first_person && q.is_item_name_any('slot.weapon.mainhand', 0, '${nameData.fullname}')`, bones: { first_person_fix: { rotation: [-40, 60, -40], position: [-3, 0, 0] }, rightarm: { position: [13.5, -10.0, 12.0], rotation: ["95.0+variable.is_using_vr*7.5", "-45.0+variable.is_using_vr*7.5", "115.0+variable.is_using_vr*-2.5"] } } },
[`animation.${nameData.namespace}.player.${nameData.shortname}.idle.third_person`]: { loop: true, override_previous_animation: true, blend_weight: `!v.is_first_person && q.is_item_name_any('slot.weapon.mainhand', 0, '${nameData.fullname}')`, bones: { rightArm: { rotation: [-30, 0, 0] } } },
[`animation.${nameData.namespace}.player.${nameData.shortname}.attack.first_person`]: { loop: "hold_on_last_frame", animation_length: 0.5, override_previous_animation: true, blend_weight: `v.is_first_person && q.is_item_name_any('slot.weapon.mainhand', 0, '${nameData.fullname}')`, bones: { first_person_fix: { rotation: [-40, 60, -40], position: [-3, 0, 0] }, rightarm: { position: [13.5, -10.0, 12.0], rotation: ["95.0+variable.is_using_vr*7.5", "-45.0+variable.is_using_vr*7.5", "115.0+variable.is_using_vr*-2.5"] }, [nameData.shortname]: { rotation: { 0.0: { post: [0, 0, 0], lerp_mode: "catmullrom" }, 0.1: { post: [-50, -40, 60], lerp_mode: "catmullrom" }, 0.2: [0, 0, -10], 0.3: [11.2376, 4.58608, -83.35255], 0.4: [0, 0, -80], 0.5: { pre: [0, 0, 0], post: [0, 0, 0], lerp_mode: "catmullrom" } }, position: { 0.0: { post: [0, 0, 0], lerp_mode: "catmullrom" }, 0.1: { post: [-7, 1, -11], lerp_mode: "catmullrom" }, 0.2: [20, -10, 10], 0.3: [23.43926, -13.01119, 15.34095], 0.4: [20, -10, 10], 0.5: { pre: [0, 0, 0], post: [0, 0, 0], lerp_mode: "catmullrom" } } } }, timeline: { 0.0: "v.playing_custom_attack = 1;", 0.5: "v.playing_custom_attack = 0;" } },
[`animation.${nameData.namespace}.player.${nameData.shortname}.attack.third_person`]: { loop: "hold_on_last_frame", override_previous_animation: true, blend_weight: `!v.is_first_person && q.is_item_name_any('slot.weapon.mainhand', 0, '${nameData.fullname}')`, animation_length: 0.3, timeline: { "0": "v.playing_custom_attack = 1;", 0.3: "v.playing_custom_attack = 0;" }, bones: { rightArm: { rotation: { 0.0: [-90, 0, 0], 0.1: [-100, 20, 0], 0.2: [-100, -20, 0], 0.3: [-90, 0, 0] } } } },
[`animation.${nameData.namespace}.item.${nameData.shortname}.idle.first_person`]: { loop: true, bones: { first_person_fix: { rotation: [-40, 60, -40], position: [-3, 0, 0] } } },
[`animation.${nameData.namespace}.item.${nameData.shortname}.idle.third_person`]: {},
[`animation.${nameData.namespace}.item.${nameData.shortname}.attack.first_person`]: { loop: "hold_on_last_frame", animation_length: 0.5, bones: { first_person_fix: { rotation: [-40, 60, -40], position: [-3, 0, 0] }, [nameData.shortname]: { rotation: { 0.0: { post: [0, 0, 0], lerp_mode: "catmullrom" }, 0.1: { post: [-50, -40, 60], lerp_mode: "catmullrom" }, 0.2: [0, 0, -10], 0.3: [11.2376, 4.58608, -83.35255], 0.4: [0, 0, -80], 0.5: { pre: [0, 0, 0], post: [0, 0, 0], lerp_mode: "catmullrom" } }, position: { 0.0: { post: [0, 0, 0], lerp_mode: "catmullrom" }, 0.1: { post: [-7, 1, -11], lerp_mode: "catmullrom" }, 0.2: [20, -10, 10], 0.3: [23.43926, -13.01119, 15.34095], 0.4: [20, -10, 10], 0.5: { pre: [0, 0, 0], post: [0, 0, 0], lerp_mode: "catmullrom" } } } }, timeline: { 0.0: "v.playing_custom_attack = 1;", 0.5: "v.playing_custom_attack = 0;" } },
[`animation.${nameData.namespace}.item.${nameData.shortname}.attack.third_person`]: {},
}
});
files.push(animation.toFile());
// attachable
const attachable = ClientAttachable.createFromTemplate(nameData);
attachable.addAnimation({ name: `ctrl.${nameData.shortname}`, reference: `controller.animation.${nameData.namespace}.item.custom_items.${nameData.shortname}` }, { name: `${nameData.shortname}.idle.first_person`, reference: `animation.${nameData.namespace}.item.${nameData.shortname}.idle.first_person` }, { name: `${nameData.shortname}.idle.third_person`, reference: `animation.${nameData.namespace}.item.${nameData.shortname}.idle.third_person` }, { name: `${nameData.shortname}.attack.first_person`, reference: `animation.${nameData.namespace}.item.${nameData.shortname}.attack.first_person` }, { name: `${nameData.shortname}.attack.third_person`, reference: `animation.${nameData.namespace}.item.${nameData.shortname}.attack.third_person` });
attachable.addAnimateScript(`ctrl.${nameData.shortname}`);
files.push(attachable.toFile());
// geometry
const geometry = ClientGeometryAttachable.createFromTemplate(nameData);
files.push(geometry.toFile());
copySourceFile('images/sprite.png', Directories.RESOURCE_PATH + 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + '.png');
files.push(ClientItemTexture.fileWithAddedTextures({ name: nameData.shortname, texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname }));
return files;
},
food: function (nameData, options) {
const item = ServerItem.createFromTemplate(nameData);
item.setDisplayData(nameData);
item.setStackSize(options.stack);
if (options.cooldown)
item.setCooldown(options.cooldown);
item.setFood();
const files = [item.toFile()];
if (options.lang) {
files.push(...LangFile.addToAllLangs('item names', `item.${nameData.fullname}.name=${nameData.display}`).files);
}
copySourceFile('images/sprite.png', Directories.RESOURCE_PATH + 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname + '.png');
files.push(ClientItemTexture.fileWithAddedTextures({ name: nameData.shortname, texture: 'textures/' + Directories.ADDON_PATH + 'items/' + nameData.directory + nameData.shortname }));
return files;
}
};