UNPKG

bedrock-development

Version:

APIs for creating and editing files related to Minecraft Bedrock development.

275 lines (274 loc) 20.4 kB
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; } };