UNPKG

@occultus/entity-api

Version:

Star Tenon entity api and utils

165 lines (161 loc) 4.9 kB
import { Entity, ItemStack, Vector3, world } from "@minecraft/server"; import { BlockEntityData } from "../interface/BlockEntityData.js"; import { ItemStackData } from "./ItemStackData.js"; /** * 方块实体 */ export class BlockEntity { constructor() {} /** * 从一个方块实体获取实体数据 * @param entity 要获取数据的方块实体 * @returns */ static getData(entity: Entity) { const block = entity.dimension.getBlock(entity.location); if (!block) return; const data: BlockEntityData = { dimension: entity.dimension, entity: entity, location: entity.location, block: block, scoreboardObjective: world.scoreboard.getObjective( `${entity.typeId}:${entity.id}` ), }; return data; } /** * 存储物品到方块实体数据中 * * @param items 要存储的物品,可以是单个物品或物品数组 * @param data 用于存储物品的方块实体数据 */ static storeItem(items: ItemStack[] | ItemStack, data: BlockEntityData) { if (Array.isArray(items)) { this.storeWithContainer(data, items); return; } if (data.entity.hasComponent("inventory")) { this.storeWithContainer(data, items); return; } this.storeWithDynamicProperty(data, items); } /** * 摧毁方块实体数据,这会将其中存储的物品掉落在世界中 * @param data */ static destory(data: BlockEntityData) { const item = this.getStoredItem(data); if (!item) { this.remove(data); return; } if (Array.isArray(item)) { item.forEach((i) => { data.dimension.spawnItem(i, data.entity.location); }); } else { data.dimension.spawnItem(item, data.entity.location); } this.remove(data); } /** * 直接移除方块实体数据 * @param data */ static remove(data: BlockEntityData) { if (data.scoreboardObjective) world.scoreboard.removeObjective(data.scoreboardObjective); data.entity?.remove(); } /** * 清除方块实体所存储的物品 * @param data */ static clearStoredItem(data: BlockEntityData) { if (data.entity.hasComponent("inventory")) { const container = data.entity.getComponent("inventory")?.container; if (!container) return; container.clearAll(); return; } else { data.entity.setDynamicProperty("starock:storedItem"); } } /** * 获取方块实体存储的物品 * @param data * @returns 方块实体存储的物品 */ static getStoredItem( data: BlockEntityData ): ItemStack | ItemStack[] | undefined { if (data.entity.hasComponent("inventory")) { const container = data.entity.getComponent("inventory")?.container; if (!container) return; const items: ItemStack[] = []; for (let i = 0; i < container.size; i++) { const item = container.getItem(i); if (item) { items.push(item); } } return items; } const rawData = data.entity.getDynamicProperty("starock:storedItem"); if (typeof rawData !== "string") return; const itemData = JSON.parse(rawData); const item = new ItemStack(itemData.typeId, itemData.amount); if (!item.hasComponent("durability")) return item; if (!itemData.damage) return item; item.getComponent("durability")!.damage = itemData.damage; return item; } static storeWithContainer( data: BlockEntityData, item: ItemStack | ItemStack[] ) { const container = data.entity.getComponent("inventory")?.container; if (!container) return; if (Array.isArray(item)) { item.forEach((item) => { container.addItem(item); }); } else { container.addItem(item); } } static storeWithDynamicProperty(data: BlockEntityData, item: ItemStack) { const itemData: ItemStackData = { typeId: item.typeId, amount: item.amount, damage: item.getComponent("durability")?.damage, }; data.entity.setDynamicProperty( "starock:storedItem", JSON.stringify(itemData) ); console.log(JSON.stringify(itemData)); } /** * 将方块实体同步到其应该在的位置 * @param data */ synchronize(data: BlockEntityData) { const { location, entity } = data; const correctLocation = entity.getDynamicProperty( "starock:blockEntityLocation" ) as Vector3; if (equals(location, correctLocation)) return; entity.teleport(correctLocation); } } function equals(location: Vector3, correctLocation: Vector3): boolean { return ( location.x === correctLocation.x && location.y === correctLocation.y && location.z === correctLocation.z ); }