1
- import { NbtParser } from '../nbt/NbtParser.js'
2
1
import type { NbtTag } from '../nbt/index.js'
3
2
import { NbtCompound , NbtInt , NbtString } from '../nbt/index.js'
3
+ import { NbtParser } from '../nbt/NbtParser.js'
4
4
import { StringReader } from '../util/index.js'
5
- import { Holder } from './Holder.js'
6
5
import { Identifier } from './Identifier.js'
7
- import { Item } from './Item.js'
8
6
9
- export class ItemStack {
10
- private readonly item : Holder < Item | undefined >
7
+ export interface ItemComponentsProvider {
8
+ getItemComponents : ( id : Identifier ) => Map < string , NbtTag > ,
9
+ }
11
10
11
+ export class ItemStack {
12
12
constructor (
13
13
public readonly id : Identifier ,
14
14
public count : number ,
15
15
public readonly components : Map < string , NbtTag > = new Map ( ) ,
16
- ) {
17
- this . item = Holder . reference ( Item . REGISTRY , id , false )
18
- }
16
+ ) { }
19
17
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 {
21
19
if ( typeof key === 'string' ) {
22
20
key = Identifier . parse ( key )
23
21
}
@@ -27,20 +25,28 @@ export class ItemStack {
27
25
}
28
26
const value = this . components . get ( key . toString ( ) )
29
27
if ( value ) {
30
- return reader ( value )
28
+ return value
31
29
}
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
33
34
}
34
35
35
- public hasComponent ( key : string | Identifier , includeDefaultComponents : boolean = true ) : boolean {
36
+ public hasComponent ( key : string | Identifier , baseComponents ?: ItemComponentsProvider ) : boolean {
36
37
if ( typeof key === 'string' ) {
37
38
key = Identifier . parse ( key )
38
39
}
39
40
if ( this . components . has ( '!' + key . toString ( ) ) ) {
40
41
return false
41
42
}
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
44
50
}
45
51
46
52
public clone ( ) : ItemStack {
@@ -85,7 +91,9 @@ export class ItemStack {
85
91
public toString ( ) {
86
92
let result = this . id . toString ( )
87
93
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 ( ',' ) } ]`
89
97
}
90
98
if ( this . count > 1 ) {
91
99
result += ` ${ this . count } `
@@ -123,12 +131,12 @@ export class ItemStack {
123
131
reader . skip ( )
124
132
}
125
133
const component = Identifier . parse ( reader . getRead ( start ) ) . toString ( )
126
- if ( ! reader . canRead ( ) ) break ;
134
+ if ( ! reader . canRead ( ) ) break
127
135
reader . skip ( )
128
136
const tag = NbtParser . readTag ( reader )
129
137
components . set ( component , tag )
130
138
}
131
- if ( ! reader . canRead ( ) ) break ;
139
+ if ( ! reader . canRead ( ) ) break
132
140
if ( reader . peek ( ) === ']' ) {
133
141
return new ItemStack ( itemId , 1 , components )
134
142
}
@@ -156,7 +164,12 @@ export class ItemStack {
156
164
const id = Identifier . parse ( nbt . getString ( 'id' ) )
157
165
const count = nbt . hasNumber ( 'count' ) ? nbt . getNumber ( 'count' ) : 1
158
166
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
+ } )
160
173
) )
161
174
return new ItemStack ( id , count , components )
162
175
}
0 commit comments