@@ -9,39 +9,47 @@ const VALID_MATERIALS = Object.values(PhysicalMaterialPartHash)
9
9
. filter ( key => typeof key === 'string' )
10
10
. sort ( ( a , b ) => ( a < b ? - 1 : 1 ) ) ;
11
11
12
- const availableSlots = ( prefab : Prefab ) => {
13
- const slots = prefab . slots ?? { } ;
14
- const filteredEntries = Object . entries ( slots ) . filter ( ( [ key ] ) => key . startsWith ( 'Slot_' ) ) ;
12
+ const availableSlots = < TPrefab extends Prefab > ( prefab : TPrefab ) => {
13
+ const slots = Object . entries ( prefab . embedded )
14
+ . filter ( ( [ key ] ) => key . startsWith ( 'Slot_' ) )
15
+ . map ( ( [ key , entity ] ) => [ key , entity . hash ] ) as [ keyof TPrefab [ 'embedded' ] , number ] [ ] ;
15
16
16
- return Object . fromEntries ( filteredEntries ) ;
17
+ return Object . fromEntries ( slots ) as Record < keyof TPrefab [ 'embedded' ] , number > ;
17
18
} ;
18
19
19
20
const getPrefabName = ( hash : number ) =>
20
21
Object . entries ( Prefab ) . find ( ( [ _ , value ] ) => value . hash === hash ) ?. [ 0 ] ?? '<Unknown prefab hash>' ;
21
22
22
- type PrefabManager < S > = {
23
+ type PrefabManager < TPrefab extends Prefab , TEmbeddedEntity extends keyof TPrefab [ 'embedded' ] > = {
23
24
name : string ;
24
25
data : PrefabData ;
25
- slots : { [ slotName : string ] : number } ;
26
- setPosition : ( x : number , y : number , z : number ) => PrefabManager < S > ;
27
- setScale : ( scale : number ) => PrefabManager < S > ;
28
- setRotation : ( x : number , y : number , z : number , w : number ) => PrefabManager < S > ;
29
- setKinematic : ( isKinematic ?: boolean ) => PrefabManager < S > ;
30
- setServerSleeping : ( isServerSleeping ?: boolean ) => PrefabManager < S > ;
31
- setVelocity : ( x : number , y : number , z : number ) => PrefabManager < S > ;
32
- setAngularVelocity : ( x : number , y : number , z : number ) => PrefabManager < S > ;
33
- setMaterial : ( material : keyof typeof PhysicalMaterialPartHash ) => PrefabManager < S > ;
34
- setIntegrity : ( integrity : number ) => PrefabManager < S > ;
35
- setServings : ( servings : number ) => PrefabManager < S > ;
36
- setOnFire : ( isLit ?: boolean ) => PrefabManager < S > ;
37
- setGiftBoxLabel : ( label : string ) => PrefabManager < S > ;
38
- addGift : < P extends Prefab , C extends keyof P [ 'slots' ] > ( gift : PrefabManager < C > ) => PrefabManager < S > ;
39
- useSlot : < P extends Prefab , C extends keyof P [ 'slots' ] > ( slot : S , childPrefab : PrefabManager < C > ) => PrefabManager < S > ;
26
+ slots : Record < keyof TPrefab [ 'embedded' ] , number > ;
27
+ setPosition : ( x : number , y : number , z : number ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
28
+ setScale : ( scale : number ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
29
+ setRotation : ( x : number , y : number , z : number , w : number ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
30
+ setKinematic : ( isKinematic ?: boolean ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
31
+ setServerSleeping : ( isServerSleeping ?: boolean ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
32
+ setVelocity : ( x : number , y : number , z : number ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
33
+ setAngularVelocity : ( x : number , y : number , z : number ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
34
+ setMaterial : ( material : keyof typeof PhysicalMaterialPartHash ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
35
+ setIntegrity : ( integrity : number ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
36
+ setServings : ( servings : number ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
37
+ setOnFire : ( isLit ?: boolean ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
38
+ setGiftBoxLabel : ( label : string ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
39
+ addGift : < TChildEmbeddedEntity extends keyof TPrefab [ 'embedded' ] > (
40
+ gift : PrefabManager < TPrefab , TChildEmbeddedEntity >
41
+ ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
42
+ useSlot : < TChildPrefab extends Prefab , TChildEmbeddedEntity extends keyof TChildPrefab [ 'embedded' ] > (
43
+ slotName : TEmbeddedEntity ,
44
+ childPrefab : PrefabManager < TChildPrefab , TChildEmbeddedEntity >
45
+ ) => PrefabManager < TPrefab , TEmbeddedEntity > ;
40
46
toString : ( ) => string ;
41
47
print : ( ) => void ;
42
48
} ;
43
49
44
- export const createPrefab = < P extends Prefab , S extends keyof P [ 'slots' ] > ( prefab : P ) : PrefabManager < S > => ( {
50
+ export const createPrefab = < TPrefab extends Prefab , TEmbeddedEntity extends keyof TPrefab [ 'embedded' ] > (
51
+ prefab : TPrefab
52
+ ) : PrefabManager < TPrefab , TEmbeddedEntity > => ( {
45
53
name : getPrefabName ( prefab . hash ) ,
46
54
47
55
data : {
@@ -253,12 +261,12 @@ export const createPrefab = <P extends Prefab, S extends keyof P['slots']>(prefa
253
261
throw new Error ( `useSlot(slot, prefab) called with invalid arguments.` ) ;
254
262
}
255
263
256
- const slotHash = ( ( this . slots as P [ 'slots' ] | undefined ) ?. [ slotName ] ?? 0 ) as number ;
264
+ const slotHash = ( this . slots ?. [ slotName ] ?? 0 ) as number ;
257
265
const validHashes = Object . values ( this . slots ) ;
258
266
259
267
if ( slotHash === 0 || ! validHashes . includes ( slotHash ) ) {
260
268
throw new Error (
261
- `'${ slotName } ' is not a valid slot on '${ this . name } '. ${
269
+ `'${ String ( slotName ) } ' is not a valid slot on '${ this . name } '. ${
262
270
validHashes . length
263
271
? `Valid slot(s): ${ Object . keys ( this . slots ) . join ( ', ' ) } `
264
272
: 'This prefab has no available slots.'
0 commit comments