diff --git a/prismarine-viewer/viewer/lib/entities.ts b/prismarine-viewer/viewer/lib/entities.ts index 48efb577..2a0ddeee 100644 --- a/prismarine-viewer/viewer/lib/entities.ts +++ b/prismarine-viewer/viewer/lib/entities.ts @@ -225,6 +225,7 @@ export class Entities extends EventEmitter { size?: number; } | { resolvedModel: BlockModel + modelName: string }) constructor (public viewer: Viewer) { @@ -426,7 +427,7 @@ export class Entities extends EventEmitter { getItemMesh (item, isDropped = false) { const textureUv = this.getItemUv?.(item) if (textureUv && 'resolvedModel' in textureUv) { - const mesh = getBlockMeshFromModel(this.viewer.world.material, textureUv.resolvedModel, item.name ?? item.itemId) + const mesh = getBlockMeshFromModel(this.viewer.world.material, textureUv.resolvedModel, textureUv.modelName) if (isDropped) { const SCALE = 0.5 mesh.scale.set(SCALE, SCALE, SCALE) diff --git a/prismarine-viewer/viewer/lib/holdingBlock.ts b/prismarine-viewer/viewer/lib/holdingBlock.ts index 42581e81..641a2813 100644 --- a/prismarine-viewer/viewer/lib/holdingBlock.ts +++ b/prismarine-viewer/viewer/lib/holdingBlock.ts @@ -249,7 +249,7 @@ export default class HoldingBlock { this.objectOuterGroup.scale.set(scale, scale, scale) } - async initHandObject (material: THREE.Material, blockstatesModels: any, blocksAtlases: any, handItem?: HandItemBlock) { + async initHandObject (handItem?: HandItemBlock) { let animatingCurrent = false if (!this.swingAnimation && !this.blockSwapAnimation && this.isDifferentItem(handItem)) { animatingCurrent = true @@ -414,7 +414,7 @@ export default class HoldingBlock { } export const getBlockMeshFromModel = (material: THREE.Material, model: BlockModel, name: string) => { - const blockProvider = worldBlockProvider(viewer.world.blockstatesModels, viewer.world.blocksAtlases, 'latest') + const blockProvider = worldBlockProvider(viewer.world.blockstatesModels, viewer.world.blocksAtlasParser!.atlas, 'latest') const worldRenderModel = blockProvider.transformModel(model, { name, properties: {} diff --git a/prismarine-viewer/viewer/lib/worldrendererCommon.ts b/prismarine-viewer/viewer/lib/worldrendererCommon.ts index 59d22dd9..327298af 100644 --- a/prismarine-viewer/viewer/lib/worldrendererCommon.ts +++ b/prismarine-viewer/viewer/lib/worldrendererCommon.ts @@ -117,8 +117,10 @@ export abstract class WorldRendererCommon itemsAtlasParser: AtlasParser | undefined blocksAtlasParser: AtlasParser | undefined - blocksAtlases = blocksAtlases - itemsAtlases = itemsAtlases + sourceData = { + blocksAtlases, + itemsAtlases + } customTextures: { items?: CustomTexturesData blocks?: CustomTexturesData @@ -320,8 +322,8 @@ export abstract class WorldRendererCommon } async updateTexturesData (resourcePackUpdate = false, prioritizeBlockTextures?: string[]) { - const blocksAssetsParser = new AtlasParser(this.blocksAtlases, blocksAtlasLatest, blocksAtlasLegacy) - const itemsAssetsParser = new AtlasParser(this.itemsAtlases, itemsAtlasLatest, itemsAtlasLegacy) + const blocksAssetsParser = new AtlasParser(this.sourceData.blocksAtlases, blocksAtlasLatest, blocksAtlasLegacy) + const itemsAssetsParser = new AtlasParser(this.sourceData.itemsAtlases, itemsAtlasLatest, itemsAtlasLegacy) const blockTexturesChanges = {} as Record const date = new Date() diff --git a/prismarine-viewer/viewer/lib/worldrendererThree.ts b/prismarine-viewer/viewer/lib/worldrendererThree.ts index 1845c98c..cab84b7b 100644 --- a/prismarine-viewer/viewer/lib/worldrendererThree.ts +++ b/prismarine-viewer/viewer/lib/worldrendererThree.ts @@ -67,7 +67,7 @@ export class WorldRendererThree extends WorldRendererCommon { holdingBlock.toBeRenderedItem = item return } - void holdingBlock.initHandObject(this.material, this.blockstatesModels, this.blocksAtlases, item) + void holdingBlock.initHandObject(item) } changeHandSwingingState (isAnimationPlaying: boolean, isLeft = false) { diff --git a/src/index.ts b/src/index.ts index 2fc886d5..77db040e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -181,6 +181,7 @@ viewer.entities.getItemUv = (item) => { if (renderInfo.blockData) { return { resolvedModel: renderInfo.blockData.resolvedModel, + modelName: renderInfo.modelName! } } if (renderInfo.slice) { diff --git a/src/inventoryWindows.ts b/src/inventoryWindows.ts index bfe96739..931348b5 100644 --- a/src/inventoryWindows.ts +++ b/src/inventoryWindows.ts @@ -179,6 +179,7 @@ export const renderSlot = (slot: GeneralInputItem, debugIsQuickbar = false): { blockData?: Record & { resolvedModel: BlockModel }, scale?: number, slice?: number[], + modelName?: string } | undefined => { let itemModelName = slot.name const originalItemName = itemModelName @@ -212,7 +213,8 @@ export const renderSlot = (slot: GeneralInputItem, debugIsQuickbar = false): { // is block return { texture: 'blocks', - blockData: itemTexture + blockData: itemTexture, + modelName: itemModelName } } } diff --git a/src/resourcePack.ts b/src/resourcePack.ts index 06bc2ce6..faea8ff7 100644 --- a/src/resourcePack.ts +++ b/src/resourcePack.ts @@ -460,11 +460,11 @@ const updateAllReplacableTextures = async () => { const repeatArr = (arr, i) => Array.from({ length: i }, () => arr) const updateTextures = async () => { - const blocksFiles = Object.keys(viewer.world.blocksAtlases.latest.textures) - const itemsFiles = Object.keys(viewer.world.itemsAtlases.latest.textures) + const origBlocksFiles = Object.keys(viewer.world.sourceData.blocksAtlases.latest.textures) + const origItemsFiles = Object.keys(viewer.world.sourceData.itemsAtlases.latest.textures) const { usedTextures: extraBlockTextures = new Set() } = await prepareBlockstatesAndModels() ?? {} - const blocksData = await getResourcepackTiles('blocks', [...blocksFiles, ...extraBlockTextures]) - const itemsData = await getResourcepackTiles('items', itemsFiles) + const blocksData = await getResourcepackTiles('blocks', [...origBlocksFiles, ...extraBlockTextures]) + const itemsData = await getResourcepackTiles('items', origItemsFiles) await updateAllReplacableTextures() viewer.world.customTextures = {} if (blocksData) { diff --git a/src/resourcePackItemDefinitions.ts b/src/resourcePackItemDefinitions.ts new file mode 100644 index 00000000..9ec0b430 --- /dev/null +++ b/src/resourcePackItemDefinitions.ts @@ -0,0 +1,48 @@ +import fs from 'fs' + +export type ResourcePackItemDefinition = { + model: { + type: 'minecraft:model' + model: string + tints?: Array<{ + type: 'minecraft:constant' + value: number // eg 12596533 + }> + } | { + type: 'minecraft:empty' + } +} + +export type ItemDefinitions = Record + +export type ItemRenderDefinitionInput = { + item: string +} + +const readFilesSafe = async (path: string) => { + try { + return await fs.promises.readdir(path) + } catch (error) { + return null + } +} + +export const readResourcePackItemDefinitions = async (assetsPath: string) => { + const namespaces = fs.readdirSync(assetsPath) + + const itemDefinitions: ItemDefinitions = {} + for (const namespace of namespaces) { + // eslint-disable-next-line no-await-in-loop + const items = await readFilesSafe(`${assetsPath}/${namespace}/items`) + if (!items) continue + for (const item of items) { + if (!item.endsWith('.json')) continue + const file = fs.readFileSync(`${assetsPath}/${namespace}/items/${item}`, 'utf8') + const json = JSON.parse(file) + itemDefinitions[`${namespace}:${item}`] = json + } + } + return itemDefinitions +} + +export const itemsDefaultNamespace = 'minecraft'