UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

361 lines (359 loc) 17.4 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", { value: true }); const BlockCube_1 = require("./BlockCube"); const NbtBinary_1 = require("./NbtBinary"); const NbtBinaryTag_1 = require("./NbtBinaryTag"); const MinecraftUtilities_1 = require("./MinecraftUtilities"); const Block_1 = require("./Block"); const Entity_1 = require("./Entity"); const Log_1 = require("../core/Log"); const Database_1 = require("./Database"); const EntityInventoryComponent_1 = require("./components/EntityInventoryComponent"); class Structure { constructor() { this._blockPalette = []; this.defaultBlockPersistenceVersion = 17879555; } get cube() { return this._cube; } set cube(newCube) { this._cube = newCube; } get entities() { return this._entities; } shallowCopyFrom(structure) { this.cube = structure.cube; this._entities = structure.entities; this.originX = structure.originX; this.originY = structure.originY; this.originZ = structure.originZ; } createNbt() { if (this._cube === undefined) { return; } const nbt = new NbtBinary_1.default(); const root = nbt.ensureSingleRoot(); root.addTag(NbtBinaryTag_1.NbtTagType.int, "format_version").value = 1; const sizeList = root.addTag(NbtBinaryTag_1.NbtTagType.list, "size"); sizeList.childTagType = NbtBinaryTag_1.NbtTagType.unknown; sizeList.addTag(NbtBinaryTag_1.NbtTagType.int).value = this._cube.maxX; sizeList.addTag(NbtBinaryTag_1.NbtTagType.int).value = this._cube.maxY; sizeList.addTag(NbtBinaryTag_1.NbtTagType.int).value = this._cube.maxZ; const structure = root.addTag(NbtBinaryTag_1.NbtTagType.compound, "structure"); const blockIndices = structure.addTag(NbtBinaryTag_1.NbtTagType.list, "block_indices"); const primaryLayer = blockIndices.addTag(NbtBinaryTag_1.NbtTagType.list); const secondaryLayer = blockIndices.addTag(NbtBinaryTag_1.NbtTagType.list); const blockPalette = {}; const paletteBlocks = []; for (let x = 0; x < this._cube.maxX; x++) { for (let y = 0; y < this._cube.maxY; y++) { for (let z = 0; z < this._cube.maxZ; z++) { const block = this._cube.x(x).y(y).z(z); const blockFingerprint = block.toString(); let paletteId = blockPalette[blockFingerprint]; if (block.typeName == null || block.typeName === "air") { paletteId = -1; } else if (paletteId == null) { paletteId = paletteBlocks.length; blockPalette[blockFingerprint] = paletteId; paletteBlocks.push(block); } primaryLayer.addTag(NbtBinaryTag_1.NbtTagType.int).value = paletteId; secondaryLayer.addTag(NbtBinaryTag_1.NbtTagType.int).value = block.extraLiquidDepth; } } } /*const entities = */ structure.addTag(NbtBinaryTag_1.NbtTagType.list, "entities"); if (this._entities !== undefined) { } const palette = structure.addTag(NbtBinaryTag_1.NbtTagType.compound, "palette"); structure.addTag(NbtBinaryTag_1.NbtTagType.end); const paletteDefault = palette.addTag(NbtBinaryTag_1.NbtTagType.compound, "default"); palette.addTag(NbtBinaryTag_1.NbtTagType.end); const blockStates = paletteDefault.addTag(NbtBinaryTag_1.NbtTagType.list, "block_palette"); for (let i = 0; i < paletteBlocks.length; i++) { const block = paletteBlocks[i]; if (block.typeName == null) { throw new Error("Unexpected palette block."); } const blockState = blockStates.addTag(NbtBinaryTag_1.NbtTagType.compound); blockState.addTag(NbtBinaryTag_1.NbtTagType.string, "name").value = block.typeName; const blockStateStates = blockState.addTag(NbtBinaryTag_1.NbtTagType.compound, "states"); for (const propertyName in block.properties) { const blockProperty = block.getProperty(propertyName); const propType = blockProperty.nbtType; const value = blockProperty.value; if (value === undefined) { blockStateStates.addTag(propType, propertyName).value = null; } else { blockStateStates.addTag(propType, propertyName).value = value; } } let version = block.persistenceVersion; if (version <= 0) { version = this.defaultBlockPersistenceVersion; } blockState.addTag(NbtBinaryTag_1.NbtTagType.int, "version").value = version; blockState.addTag(NbtBinaryTag_1.NbtTagType.end); } // TODO: add block_position_data here to paletteDefault; const blockPositionData = paletteDefault.addTag(NbtBinaryTag_1.NbtTagType.compound, "block_position_data"); blockPositionData.addTag(NbtBinaryTag_1.NbtTagType.end); paletteDefault.addTag(NbtBinaryTag_1.NbtTagType.end); if (this.originX !== undefined && this.originY !== undefined && this.originZ !== undefined) { const structureOrigin = root.addTag(NbtBinaryTag_1.NbtTagType.list, "structure_world_origin"); structureOrigin.addTag(NbtBinaryTag_1.NbtTagType.int).value = this.originX; structureOrigin.addTag(NbtBinaryTag_1.NbtTagType.int).value = this.originY; structureOrigin.addTag(NbtBinaryTag_1.NbtTagType.int).value = this.originZ; } root.addTag(NbtBinaryTag_1.NbtTagType.end); return nbt; } loadFromSnbtText(text) { let structure = null; const content = MinecraftUtilities_1.default.fixupJson(text); try { // temporarily putting back in the safe code. structure = JSON.stringify(content); // eval('(' + content + ')'); } catch (e) { throw new Error("Error processing SNBT."); } if (structure === null || structure === undefined) { throw new Error("Could not create SNBT."); } } loadFromSnbt(content) { if (content.size === null || content.size === undefined || content.size.length !== 3 || content.data === undefined) { throw new Error("Unexpected structure to Snbt file."); } if (this._cube === undefined) { this._cube = new BlockCube_1.default(); } this._cube.setMaxDimensions(content.size[0], content.size[1], content.size[2]); for (let i = 0; i < content.data.length; i++) { const block = content.data[i]; if (block.pos === undefined || block.pos.length !== 3 || block.state === undefined) { throw new Error("Unexpected format for a block in an Snbt"); } const targetBlock = this._cube.x(block.pos[0]).y(block.pos[1]).z(block.pos[2]); let blockTypeId = block.state; const firstCurly = blockTypeId.indexOf("{"); if (firstCurly >= 0) { if (blockTypeId[blockTypeId.length - 1] !== "}") { throw new Error("Unexpected property found."); } const props = blockTypeId.substring(firstCurly + 1, blockTypeId.length - 1).split(","); for (const prop of props) { const propArr = prop.split(":"); if (propArr.length === 2) { targetBlock.ensureProperty(propArr[0]).value = propArr[1]; } else { throw new Error("Unexpected property found."); } } blockTypeId = blockTypeId.substring(0, firstCurly); } targetBlock.typeName = blockTypeId; } } async loadFromNbtBytes(bytes) { const tag = new NbtBinary_1.default(); tag.fromBinary(bytes, true, false); this.nbt = tag; await this.loadFromNbt(tag); } getMCStructureBytes() { if (this.originX === undefined) { this.originX = 10; } if (this.originY === undefined) { this.originY = 10; } if (this.originZ === undefined) { this.originZ = 10; } const nbt = this.createNbt(); if (nbt !== undefined) { const bytes = nbt.toBinary(); return bytes; } Log_1.default.fail("Could not create MC Structure bytes for updated."); return undefined; } async loadFromNbt(binary) { const cube = new BlockCube_1.default(); const root = binary.singleRoot; if (root === null) { return; } const paletteTag = root.find("block_palette"); const indicesTag = root.find("block_indices"); const sizeTag = root.find("size"); if (paletteTag === null || sizeTag === null || indicesTag === null || sizeTag.getTagChildren().length !== 3 || indicesTag.getTagChildren().length !== 2) { return; } const sizeTagChildren = sizeTag.getTagChildren(); const indicesChildren = indicesTag.getTagChildren(); const paletteTagChildren = paletteTag.getTagChildren(); cube.setMaxDimensions(sizeTagChildren[0].value, sizeTagChildren[1].value, sizeTagChildren[2].value); this._blockPalette = []; for (let i = 0; i < paletteTagChildren.length; i++) { const state = paletteTagChildren[i]; const name = state.getProperty("name"); const states = state.getProperty("states"); const version = state.getProperty("version"); if (name != null && states != null && version != null) { const block = new Block_1.default(name.value); this._blockPalette.push(block); const statesChildren = states.getTagChildren(); for (let j = 0; j < statesChildren.length; j++) { const state = statesChildren[j]; const blockProp = block.ensureProperty(state.name); blockProp.nbtType = state.type; if (state.value === null) { blockProp.value = undefined; } else { blockProp.value = state.value; } } block.persistenceVersion = version.value; this.defaultBlockPersistenceVersion = block.persistenceVersion; } } const blockRefs = indicesChildren[0].getTagChildren(); let i = 0; for (let x = 0; x < cube.maxX; x++) { for (let y = 0; y < cube.maxY; y++) { for (let z = 0; z < cube.maxZ; z++) { const blockRefNum = blockRefs[i].value; const block = cube.x(x).y(y).z(z); if (blockRefNum === -1) { block.typeName = "minecraft:air"; } else { block.applyFrom(this._blockPalette[blockRefNum]); } block.extraLiquidDepth = -1; i++; } } } const waterLevels = indicesChildren[1].getTagChildren(); i = 0; for (let x = 0; x < cube.maxX; x++) { for (let y = 0; y < cube.maxY; y++) { for (let z = 0; z < cube.maxZ; z++) { const secondaryBlockIndex = waterLevels[i].value; if (secondaryBlockIndex !== -1) { const block = cube.x(x).y(y).z(z); const secondaryBlock = this._blockPalette[secondaryBlockIndex]; if (secondaryBlock.shortTypeName === "water") { block.extraLiquidDepth = secondaryBlock.getPropertyNumber("liquid_depth", -1); } } i++; } } } const entities = root.find("entities"); this._entities = []; if (entities !== null) { await Database_1.default.loadUx(); if (Database_1.default.uxCatalog !== undefined) { const entitiesChildren = entities.getTagChildren(); for (let i = 0; i < entitiesChildren.length; i++) { const entityTag = entitiesChildren[i]; const entity = new Entity_1.default(); const entityTagChildren = entityTag.getTagChildren(); for (let j = 0; j < entityTagChildren.length; j++) { const entityPropertyTag = entityTagChildren[j]; if (entityPropertyTag.name === "definitions") { entity.loadDefinitionsFromNbtTag(entityPropertyTag); } else if (entityPropertyTag.name === "identifier") { Log_1.default.assert(entityPropertyTag.type === NbtBinaryTag_1.NbtTagType.string, "Expected string type"); entity.typeId = entityPropertyTag.valueAsString; } else if (entityPropertyTag.name === "Attributes") { entity.loadAttributeComponentsFromNbtTag(entityPropertyTag); } else if (entityPropertyTag.name === "Rotation") { entity.loadRotationFromNbtTag(entityPropertyTag); } else if (entityPropertyTag.name === "Tags") { entity.loadTagsFromNbtTag(entityPropertyTag); } else if (entityPropertyTag.name === "ChestItems") { const inventoryComponent = entity.ensureDataComponent("inventory", new EntityInventoryComponent_1.default()); inventoryComponent.loadFromNbtTag(entityPropertyTag); } else if (entityPropertyTag.name === "Armor") { const inventoryComponent = entity.ensureDataComponent("armor_inventory", new EntityInventoryComponent_1.default()); inventoryComponent.loadFromNbtTag(entityPropertyTag); } else if (entityPropertyTag.name === "Mainhand") { const subElement = entityPropertyTag.getTagChildren(); if (subElement.length === 1) { const inventoryComponent = entity.ensureDataComponent("mainhand", new EntityInventoryComponent_1.default()); inventoryComponent.loadFromNbtTag(entityPropertyTag); } } else if (entityPropertyTag.name === "Offhand") { const subElement = entityPropertyTag.getTagChildren(); if (subElement.length === 1) { const inventoryComponent = entity.ensureDataComponent("offhand", new EntityInventoryComponent_1.default()); inventoryComponent.loadFromNbtTag(entityPropertyTag); } } else if (entityPropertyTag.name === "Pos") { entity.loadLocationFromNbtTag(entityPropertyTag); } else if (entityPropertyTag.value === null) { const prop = entity.ensureComponentProperty(entityPropertyTag.name); prop.load(); prop.value = undefined; } else { const prop = entity.ensureComponentProperty(entityPropertyTag.name); prop.load(); prop.value = entityPropertyTag.value; } } this._entities.push(entity); } } } const structureOrigin = root.find("structure_world_origin"); if (structureOrigin !== null && structureOrigin.getTagChildren().length === 3) { const structuresOriginChildren = structureOrigin.getTagChildren(); this.originX = structuresOriginChildren[0].valueAsInt; this.originY = structuresOriginChildren[1].valueAsInt; this.originZ = structuresOriginChildren[2].valueAsInt; } else { this.originX = undefined; this.originY = undefined; this.originZ = undefined; } this._cube = cube; } } exports.default = Structure; //# sourceMappingURL=../maps/minecraft/Structure.js.map