UNPKG

@bdsx/containermenu

Version:

ContainerMenu - An API allowing you to create fake container menus.

285 lines 18.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FakeContainer = void 0; const inventory_1 = require("bdsx/bds/inventory"); const packets_1 = require("bdsx/bds/packets"); const launcher_1 = require("bdsx/launcher"); const PlayerManager_1 = require("../PlayerManager"); const Utils_1 = require("../utils/Utils"); const nbt_1 = require("bdsx/bds/nbt"); const nativetype_1 = require("bdsx/nativetype"); class FakeContainer { constructor(block, containerType, containerSize, player, destructItems = true, inventory = {}) { this.netId = player.getNetworkIdentifier(); this.containerId = player.nextContainerCounter(); this.block = block; this.containerType = containerType; this.containerSize = containerSize; this.destructItems = destructItems; this.inventory = inventory; } /** * Places the container client-side. * This is required in Bedrock edition. */ placeContainer(pos) { const pk = packets_1.UpdateBlockPacket.allocate(); pk.blockPos.construct(pos); pk.dataLayerId = 0; pk.flags = packets_1.UpdateBlockPacket.Flags.Network; pk.blockRuntimeId = this.block.getRuntimeId(); pk.sendTo(this.netId); pk.dispose(); } /** * Opens the container client-side. */ openContainer() { const pk = packets_1.ContainerOpenPacket.allocate(); pk.containerId = this.containerId; pk.type = this.containerType; pk.pos.construct(this.position); pk.sendTo(this.netId); pk.dispose(); } /** * Force-closes the container client-side. * * @remarks This will destruct the container */ closeContainer() { const pk = packets_1.ContainerClosePacket.allocate(); pk.containerId = this.containerId; pk.server = true; pk.sendTo(this.netId); pk.dispose(); } /** * Sends the fake container to the client. */ sendToPlayer() { PlayerManager_1.PlayerManager.setContainer(this.netId, this); this.position = Utils_1.Utils.getAbovePosition(this.netId); this.placeContainer(this.position); if (this.customName) this.sendCustomName(); launcher_1.bedrockServer.serverInstance.nextTick().then(() => { this.openContainer(); this.updateAllItems(); }); } /** * Sets an item in the container. * * @param slot - The slot to set the item in. * @param item - The item to set. * @param destructOld - Whether to destroy the old item. * * * @remarks This will update the item client-side if needed to. */ setItem(slot, item, destructOld = this.destructItems) { var _a; if (slot < 0 || slot >= this.containerSize) { throw new Error(`Slot ${slot} is out of range (container has ${this.containerSize} slots)`); } if (this.inventory[slot] !== undefined && !((_a = this.inventory[slot]) === null || _a === void 0 ? void 0 : _a.sameItem(item)) && destructOld) this.inventory[slot].destruct(); this.inventory[slot] = item; // If the container is not sent yet, no need to update the slot. if (PlayerManager_1.PlayerManager.hasContainer(this.netId)) { this.updateItem(slot, item); } } /** * Sets the container's inventory contents. * * @param contents - The contents to set. * @param destructOld - Whether to destroy the old items. */ setContents(contents, destructOld = this.destructItems) { for (const [slot, item] of Object.entries(contents)) { this.setItem(+slot, item, destructOld); } } /** * Adds an item to the container * * @param item - The item to add. */ addItem(item) { for (let i = 0; i < this.containerSize; i++) { if (!this.inventory[i]) { this.setItem(i, item); return; } } } /** * Updates a single item in the container's inventory client-side. */ updateItem(slot, item) { if (slot < 0 || slot >= this.containerSize) { throw new Error(`Slot ${slot} is out of range (container has ${this.containerSize} slots)`); } const pk = packets_1.InventorySlotPacket.allocate(); pk.containerId = this.containerId; pk.slot = slot; const descriptor = inventory_1.NetworkItemStackDescriptor.constructWith(item); pk.descriptor.destruct(); pk.descriptor[nativetype_1.NativeType.ctor_move](descriptor); pk.sendTo(this.netId); descriptor.destruct(); pk.dispose(); } /** * Updates the container's inventory client-side. */ updateAllItems() { for (let [slot, item] of Object.entries(this.inventory)) { this.updateItem(+slot, item); } } /** * Returns the item at the specified slot. * * @param slot - The slot to get the item from. */ getItem(slot) { if (slot < 0 || slot >= this.containerSize) { throw new Error(`Slot ${slot} is out of range (container has ${this.containerSize} slots)`); } return this.inventory[slot]; } /** * Returns the contents of the container. */ getContents() { return this.inventory; } /** * Clears a container's slot, * updating it client-side if needed. */ clearItem(slot, destructItem = this.destructItems) { if (slot < 0 || slot >= this.containerSize) { throw new Error(`Slot ${slot} is out of range (container has ${this.containerSize} slots)`); } if (this.inventory[slot]) { if (destructItem) this.inventory[slot].destruct(); delete this.inventory[slot]; // If the container is not sent yet, no need to update the slot. if (PlayerManager_1.PlayerManager.hasContainer(this.netId)) { this.updateItem(slot, inventory_1.ItemStack.EMPTY_ITEM); } } } /** * Clears the container's contents, * updating it client-side if needed. */ clearContents(destructItems = this.destructItems) { for (const [slot, item] of Object.entries(this.inventory)) { this.clearItem(+slot, destructItems); } } /** * Sets a custom name to the container. * * @param name - The name to set. * * @remarks This needs to be set BEFORE sending the container. */ setCustomName(name) { this.customName = name; } /** * Sends the container's custom name to the client. */ sendCustomName() { const tag = nbt_1.StringTag.constructWith(this.customName); const pk = packets_1.BlockActorDataPacket.allocate(); pk.pos.set(this.position); pk.data.set("CustomName", tag); pk.sendTo(this.netId); pk.dispose(); tag.destruct(); } /** * Callback is triggered when the player interacts with an item, * in the container, or in its inventory. */ onTransaction(callback) { this.transactionCallback = callback; } /** * Returns whether a transaction callback is set. */ hasTransactionCallback() { return this.transactionCallback !== undefined; } /** * Calls the transaction callback. */ callTransactionCallback(action) { if (this.hasTransactionCallback()) return this.transactionCallback(action); } /** * Callback is triggered when the player closes the container, or is forced to do so. */ onContainerClose(callback) { this.containerCloseCallback = callback; } /** * Returns whether a container close callback is set. */ hasContainerCloseCallback() { return this.containerCloseCallback !== undefined; } /** * Calls the container close callback. */ callContainerCloseCallback() { if (this.hasContainerCloseCallback()) this.containerCloseCallback(); this.destruct(); } /** * Destroys the container client-side, * and replaces it with the original block. */ destroyContainer(pos) { const pk = packets_1.UpdateBlockPacket.allocate(); pk.blockPos.construct(pos); pk.dataLayerId = 0; pk.flags = packets_1.UpdateBlockPacket.Flags.Network; pk.blockRuntimeId = Utils_1.Utils.getBlockAtPosition(this.netId, pos).getRuntimeId(); pk.sendTo(this.netId); pk.dispose(); } /** * Destructs all the ItemStack instances of the container's inventory. * * @remarks This is called automatically if `destructItems` is set to true. */ destructAllItems() { for (const item of Object.values(this.inventory)) { item.destruct(); } this.inventory = {}; } /** * Destroys the container, and destructs all the ItemStack instances, if needed. */ destruct() { this.destroyContainer(this.position); if (this.destructItems) { this.destructAllItems(); } PlayerManager_1.PlayerManager.removeContainer(this.netId); } } exports.FakeContainer = FakeContainer; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmFrZUNvbnRhaW5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIkZha2VDb250YWluZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0Esa0RBQTBGO0FBRTFGLDhDQU8wQjtBQUUxQiw0Q0FBOEM7QUFFOUMsb0RBQWlEO0FBQ2pELDBDQUF1QztBQUV2QyxzQ0FBeUM7QUFFekMsZ0RBQTZDO0FBSzdDLE1BQWEsYUFBYTtJQWN0QixZQUFZLEtBQVksRUFBRSxhQUE0QixFQUFFLGFBQXFCLEVBQUUsTUFBb0IsRUFBRSxnQkFBeUIsSUFBSSxFQUFFLFlBQWdDLEVBQUU7UUFDbEssSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUMzQyxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQ2pELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO1FBQ25DLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO1FBQ25DLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO1FBQ25DLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0lBQy9CLENBQUM7SUFFRDs7O09BR0c7SUFDTyxjQUFjLENBQUMsR0FBYTtRQUNsQyxNQUFNLEVBQUUsR0FBRywyQkFBaUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN4QyxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzQixFQUFFLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNuQixFQUFFLENBQUMsS0FBSyxHQUFHLDJCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDM0MsRUFBRSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzlDLEVBQUUsQ0FBQyxN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