Skip to content

Commit a820998

Browse files
committed
Refactor item stack default components
1 parent 8774cb2 commit a820998

11 files changed

+232
-213
lines changed

demo/main.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { mat4 } from 'gl-matrix'
22
import type { ItemRendererResources, ItemRenderingContext, NbtTag, Resources, Voxel } from '../src/index.js'
3-
import { BlockDefinition, BlockModel, Identifier, Item, ItemRenderer, ItemStack, NormalNoise, Structure, StructureRenderer, TextureAtlas, VoxelRenderer, XoroshiroRandom, jsonToNbt, upperPowerOfTwo } from '../src/index.js'
3+
import { BlockDefinition, BlockModel, Identifier, ItemRenderer, ItemStack, jsonToNbt, NormalNoise, Structure, StructureRenderer, TextureAtlas, upperPowerOfTwo, VoxelRenderer, XoroshiroRandom } from '../src/index.js'
44
import { } from '../src/nbt/Util.js'
55
import { ItemModel } from '../src/render/ItemModel.js'
66

@@ -107,13 +107,13 @@ Promise.all([
107107
itemModels['minecraft:' + id] = ItemModel.fromJson(item_models[id].model)
108108
})
109109

110-
110+
const itemComponents: Record<string, Map<string, NbtTag>> = {}
111111
Object.keys(item_components).forEach(id => {
112112
const components = new Map<string, NbtTag>()
113113
Object.keys(item_components[id]).forEach(c_id => {
114114
components.set(c_id, jsonToNbt(item_components[id][c_id]))
115115
})
116-
Item.REGISTRY.register(Identifier.create(id), new Item(components))
116+
itemComponents['minecraft:' + id] = components
117117
})
118118

119119
const atlasCanvas = document.createElement('canvas')
@@ -140,12 +140,13 @@ Promise.all([
140140
getBlockProperties(id) { return null },
141141
getDefaultBlockProperties(id) { return null },
142142
getItemModel(id) { return itemModels[id.toString()] },
143+
getItemComponents(id) { return itemComponents[id.toString()] },
143144
}
144145

145146
// === Item rendering ===
146147

147148
const context: ItemRenderingContext = {
148-
"bundle/selected_item": 0
149+
'bundle/selected_item': 0,
149150
}
150151

151152
const itemCanvas = document.getElementById('item-display') as HTMLCanvasElement
@@ -159,7 +160,7 @@ Promise.all([
159160
try {
160161
const id = itemInput.value
161162
const itemStack = ItemStack.fromString(itemInput.value)
162-
itemGl.clear(itemGl.DEPTH_BUFFER_BIT | itemGl.COLOR_BUFFER_BIT);
163+
itemGl.clear(itemGl.DEPTH_BUFFER_BIT | itemGl.COLOR_BUFFER_BIT)
163164
itemRenderer.setItem(itemStack, context)
164165
itemRenderer.drawItem()
165166
itemInput.classList.remove('invalid')

src/core/Item.ts

-31
This file was deleted.

src/core/ItemStack.ts

+31-18
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
import { NbtParser } from '../nbt/NbtParser.js'
21
import type { NbtTag } from '../nbt/index.js'
32
import { NbtCompound, NbtInt, NbtString } from '../nbt/index.js'
3+
import { NbtParser } from '../nbt/NbtParser.js'
44
import { StringReader } from '../util/index.js'
5-
import { Holder } from './Holder.js'
65
import { Identifier } from './Identifier.js'
7-
import { Item } from './Item.js'
86

9-
export class ItemStack {
10-
private readonly item: Holder<Item | undefined>
7+
export interface ItemComponentsProvider {
8+
getItemComponents: (id: Identifier) => Map<string, NbtTag>,
9+
}
1110

11+
export class ItemStack {
1212
constructor(
1313
public readonly id: Identifier,
1414
public count: number,
1515
public readonly components: Map<string, NbtTag> = new Map(),
16-
) {
17-
this.item = Holder.reference(Item.REGISTRY, id, false)
18-
}
16+
) {}
1917

20-
public getComponent<T>(key: string | Identifier, reader: (tag: NbtTag) => T, includeDefaultComponents: boolean = true): T | undefined {
18+
public getComponent<T>(key: string | Identifier, baseComponents?: ItemComponentsProvider): NbtTag | undefined {
2119
if (typeof key === 'string') {
2220
key = Identifier.parse(key)
2321
}
@@ -27,20 +25,28 @@ export class ItemStack {
2725
}
2826
const value = this.components.get(key.toString())
2927
if (value) {
30-
return reader(value)
28+
return value
3129
}
32-
return includeDefaultComponents ? this.item.value()?.getComponent(key, reader) : undefined
30+
if (baseComponents) {
31+
return baseComponents.getItemComponents(this.id)?.get(key.toString())
32+
}
33+
return undefined
3334
}
3435

35-
public hasComponent(key: string | Identifier, includeDefaultComponents: boolean = true): boolean {
36+
public hasComponent(key: string | Identifier, baseComponents?: ItemComponentsProvider): boolean {
3637
if (typeof key === 'string') {
3738
key = Identifier.parse(key)
3839
}
3940
if (this.components.has('!' + key.toString())){
4041
return false
4142
}
42-
43-
return this.components.has(key.toString()) || (includeDefaultComponents && (this.item.value()?.hasComponent(key) ?? false))
43+
if (this.components.has(key.toString())) {
44+
return true
45+
}
46+
if (baseComponents) {
47+
return baseComponents.getItemComponents(this.id)?.has(key.toString())
48+
}
49+
return false
4450
}
4551

4652
public clone(): ItemStack {
@@ -85,7 +91,9 @@ export class ItemStack {
8591
public toString() {
8692
let result = this.id.toString()
8793
if (this.components.size > 0) {
88-
result += `[${[...this.components.entries()].map(([k, v]) => `${k}=${v.toString()}`).join(',')}]`
94+
result += `[${[...this.components.entries()].map(([k, v]) => {
95+
return k.startsWith('!') ? k : `${k}=${v.toString()}`
96+
}).join(',')}]`
8997
}
9098
if (this.count > 1) {
9199
result += ` ${this.count}`
@@ -123,12 +131,12 @@ export class ItemStack {
123131
reader.skip()
124132
}
125133
const component = Identifier.parse(reader.getRead(start)).toString()
126-
if (!reader.canRead()) break;
134+
if (!reader.canRead()) break
127135
reader.skip()
128136
const tag = NbtParser.readTag(reader)
129137
components.set(component, tag)
130138
}
131-
if (!reader.canRead()) break;
139+
if (!reader.canRead()) break
132140
if (reader.peek() === ']'){
133141
return new ItemStack(itemId, 1, components)
134142
}
@@ -156,7 +164,12 @@ export class ItemStack {
156164
const id = Identifier.parse(nbt.getString('id'))
157165
const count = nbt.hasNumber('count') ? nbt.getNumber('count') : 1
158166
const components = new Map(Object.entries(
159-
nbt.getCompound('components').map((key, value) => [Identifier.parse(key).toString(), value])
167+
nbt.getCompound('components').map((key, value) => {
168+
if (key.startsWith('!')) {
169+
return ['!' + Identifier.parse(key).toString(), new NbtCompound()]
170+
}
171+
return [Identifier.parse(key).toString(), value]
172+
})
160173
))
161174
return new ItemStack(id, count, components)
162175
}

src/core/index.ts

-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@ export * from './Effects.js'
88
export * from './Holder.js'
99
export * from './HolderSet.js'
1010
export * from './Identifier.js'
11-
export * from './Item.js'
1211
export * from './ItemStack.js'
1312
export * from './PalettedContainer.js'
1413
export * from './Registry.js'
1514
export * from './Rotation.js'
1615
export * from './Structure.js'
1716
export * from './StructureProvider.js'
18-

0 commit comments

Comments
 (0)