mc-assets 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.MD +130 -2
- package/dist/{parser.d.ts → assetsParser.d.ts} +15 -3
- package/dist/{parser.js → assetsParser.js} +26 -13
- package/dist/atlasCreator.js +4 -0
- package/dist/atlasParser.d.ts +8 -3
- package/dist/atlasParser.js +20 -7
- package/dist/blockStatesModels.json +803 -2522
- package/dist/blocksAtlasLatest.png +0 -0
- package/dist/blocksAtlases.json +1353 -1348
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/itemsRenderer.d.ts +63 -0
- package/dist/itemsRenderer.js +78 -0
- package/dist/types.d.ts +8 -0
- package/dist/worldBlockProvider.d.ts +22 -11
- package/dist/worldBlockProvider.js +11 -14
- package/docs-assets/mc-assets.png +0 -0
- package/package.json +8 -6
- package/dist/itemsProvider.d.ts +0 -6
- package/dist/itemsProvider.js +0 -12
package/README.MD
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MC Assets
|
|
2
2
|
|
|
3
|
-

|
|
3
|
+

|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npm i mc-assets
|
|
@@ -16,8 +16,136 @@ npm i mc-assets
|
|
|
16
16
|
- **Version Accurate** - Includes all released versions starting from 1.7.10.
|
|
17
17
|
- **Memory Efficient** - Small installation size, for the fastest download & loading time.
|
|
18
18
|
- **Simple & Complete API** - Works in browsers out of the box and provides parsers for all the data this library provides.
|
|
19
|
+
- **Easy to Use Items Textures** - Includes hand-crafted isometric textures for some blocks (50% done).
|
|
20
|
+
<!-- - **Models Complete** - Includes hand-crafted models for block entities. -->
|
|
19
21
|
|
|
20
|
-
This module was originally designed as standalone package for [https://mcraft.fun](mcraft.fun) (repo) project so it is easier to maintain, but now it became a library that I think can cover any use case where you need to work with minecraft assets.
|
|
22
|
+
This module was originally designed as standalone package for [https://mcraft.fun](mcraft.fun) (repo) project so it is easier to maintain, but now it became a library that I think can cover any use case where you need to work with minecraft assets. This library means block states, models data and texture contents, it doesn't cover minecraft-data use cases.
|
|
21
23
|
|
|
22
24
|
> Bundled modules & block states are version-accurate starting from 1.13.0 (post-flattening) version.
|
|
23
25
|
> Tested on Node.js 18 and above.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
All blockstates + models + all atlas textures for all versions bundled: 4.5 MB.
|
|
29
|
+
|
|
30
|
+
This packages includes versions for: 1.7.10, 1.8, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.8.5, 1.8.6, 1.8.7, 1.8.8, 1.8.9, 1.9, 1.9.1, 1.9.2, 1.9.3, 1.9.4, 1.10, 1.10.1, 1.10.2, 1.11, 1.11.1, 1.11.2, 1.12, 1.12.1, 1.12.2, 1.13, 1.13.1, 1.13.2, 1.14, 1.14.1, 1.14.2, 1.14.3, 1.14.4, 1.15, 1.15.1, 1.15.2, 1.16, 1.16.1, 1.16.2, 1.16.3, 1.16.4, 1.16.5, 1.17, 1.17.1, 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2, 1.19.3, 1.19.4, 1.20, 1.20.1, 1.20.2, 1.20.3, 1.20.4, 1.20.5, 1.20.6.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
Following atlases are generated:
|
|
36
|
+
|
|
37
|
+
- Items
|
|
38
|
+
- Blocks
|
|
39
|
+
- Particles
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { AssetsParser, getLoadedModelsStore, getLoadedBlockstatesStore } from 'mc-assets'
|
|
43
|
+
import blockstatesModels from 'mc-assets/dist/blockStatesModels.json'
|
|
44
|
+
|
|
45
|
+
const blockstatesStore = getLoadedBlockstatesStore(blockstatesModels)
|
|
46
|
+
const modelsStore = getLoadedModelsStore(blockstatesModels)
|
|
47
|
+
// get block states for specific block
|
|
48
|
+
const stoneModels = blockstatesStore.get('latest', 'stone').variants['']
|
|
49
|
+
// [
|
|
50
|
+
// { model: 'block/stone' },
|
|
51
|
+
// { model: 'block/stone_mirrored' },
|
|
52
|
+
// { model: 'block/stone', y: 180 },
|
|
53
|
+
// { model: 'block/stone_mirrored', y: 180 }
|
|
54
|
+
// ]
|
|
55
|
+
const model = modelsStore.get('latest', 'block/stone_mirrored')
|
|
56
|
+
// { parent: 'block/cube_mirrored_all', textures: { all: 'block/stone' } }
|
|
57
|
+
|
|
58
|
+
// note: you can always specify a specific version instead of 'latest'
|
|
59
|
+
const assetsParser = new AssetsParser('latest', blockstatesStore, modelsStore)
|
|
60
|
+
|
|
61
|
+
const resolvedModel = assetsParser.getResolvedModel({
|
|
62
|
+
name: 'stone', // block name not model name
|
|
63
|
+
properties: {},
|
|
64
|
+
}, false) // false (default) means return empty if variant matching properties is not found
|
|
65
|
+
// {
|
|
66
|
+
// textures: {
|
|
67
|
+
// all: 'block/stone',
|
|
68
|
+
// particle: 'block/stone',
|
|
69
|
+
// down: 'block/stone',
|
|
70
|
+
// up: 'block/stone',
|
|
71
|
+
// north: 'block/stone',
|
|
72
|
+
// east: 'block/stone',
|
|
73
|
+
// south: 'block/stone',
|
|
74
|
+
// west: 'block/stone'
|
|
75
|
+
// },
|
|
76
|
+
// elements: [
|
|
77
|
+
// {
|
|
78
|
+
// from: [ 0, 0, 0 ],
|
|
79
|
+
// to: [ 16, 16, 16 ],
|
|
80
|
+
// faces: {
|
|
81
|
+
// down: { texture: 'block/stone', cullface: 'down' },
|
|
82
|
+
// up: { texture: 'block/stone', cullface: 'up' },
|
|
83
|
+
// north: { texture: 'block/stone', cullface: 'north' },
|
|
84
|
+
// south: { texture: 'block/stone', cullface: 'south' },
|
|
85
|
+
// west: { texture: 'block/stone', cullface: 'west' },
|
|
86
|
+
// east: { texture: 'block/stone', cullface: 'east' }
|
|
87
|
+
// }
|
|
88
|
+
// }
|
|
89
|
+
// ]
|
|
90
|
+
// }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Rendering Atlas Textures
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { AssetsParser, AtlasParser } from 'mc-assets'
|
|
97
|
+
import blocksAtlases from 'mc-assets/dist/blocksAtlases.json'
|
|
98
|
+
import blocksAtlasLatest from 'mc-assets/dist/blocksAtlasLatest.png'
|
|
99
|
+
import blocksAtlasLegacy from 'mc-assets/dist/blocksAtlasLegacy.png'
|
|
100
|
+
|
|
101
|
+
const atlasParser = new AtlasParser(blocksAtlases, blocksAtlasLatest, blocksAtlasLegacy) // blocksAtlasLegacy is optional
|
|
102
|
+
|
|
103
|
+
const diamondOreTexture = atlasParser.getTextureInfo('diamond_ore', '1.13') // get old diamond ore texture
|
|
104
|
+
const img = await diamondOreTexture.getLoadedImage()
|
|
105
|
+
|
|
106
|
+
const canvas = document.createElement('canvas')
|
|
107
|
+
const sourceWidthSize = img.width * diamondOreTexture.su // 16
|
|
108
|
+
const sourceHeightSize = img.width * diamondOreTexture.sv // 16
|
|
109
|
+
canvas.width = 128
|
|
110
|
+
canvas.height = 128
|
|
111
|
+
document.body.appendChild(canvas)
|
|
112
|
+
|
|
113
|
+
const ctx = canvas.getContext('2d')!
|
|
114
|
+
ctx.imageSmoothingEnabled = false
|
|
115
|
+
|
|
116
|
+
ctx.drawImage(img, diamondOreTexture.u * img.width, diamondOreTexture.v * img.height, sourceWidthSize, sourceHeightSize, 0, 0, canvas.width, canvas.height)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
// create new custom texture atlas (e.g. resource pack overrides)
|
|
121
|
+
const { atlas, canvas, newAtlasParser } = await atlasParser.makeNewAtlas('1.13') // with second argument (callback) you can override textures, with third use different tile size (use it if you have high-res textures)
|
|
122
|
+
const image = canvas.toDataURL() // get image data url if you need it
|
|
123
|
+
const diamondOreTexture = newAtlasParser.getTextureInfo('diamond_ore') // get old diamond ore texture (essentially the same as above)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Getting Other Textures
|
|
127
|
+
|
|
128
|
+
Textures without atlases are stored in `dist/other-textures` folder. You can use them like this:
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import unmute_button from 'mc-assets/dist/other-textures/latest/gui/sprites/social_interactions/unmute_button.png'
|
|
132
|
+
import unmute_button_highlighted from 'mc-assets/dist/other-textures/latest/gui/sprites/social_interactions/unmute_button_highlighted.png'
|
|
133
|
+
|
|
134
|
+
const Button = styled.button`
|
|
135
|
+
background-image: url(${unmute_button});
|
|
136
|
+
background-size: cover;
|
|
137
|
+
background-position: center;
|
|
138
|
+
background-repeat: no-repeat;
|
|
139
|
+
border: none;
|
|
140
|
+
outline: none;
|
|
141
|
+
cursor: pointer;
|
|
142
|
+
width: 32px;
|
|
143
|
+
height: 32px;
|
|
144
|
+
`
|
|
145
|
+
|
|
146
|
+
const ButtonHighlighted = styled(Button)`
|
|
147
|
+
background-image: url(${unmute_button_highlighted});
|
|
148
|
+
`
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Play with the [atlas explorer](https://zardoy.github.io/mc-assets/).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BlockModelsStore, BlockStatesStore } from './stores';
|
|
2
|
-
import { BlockElementPos } from './types';
|
|
2
|
+
import { BlockElementPos, BlockModel } from './types';
|
|
3
3
|
export interface QueriedBlock {
|
|
4
4
|
stateId: number;
|
|
5
5
|
name: string;
|
|
@@ -14,9 +14,13 @@ export declare class AssetsParser {
|
|
|
14
14
|
blockModelsStore: BlockModelsStore;
|
|
15
15
|
stateIdToElements: Record<string, BlockElement[] | 1>;
|
|
16
16
|
constructor(version: string, blockStatesStore: BlockStatesStore, blockModelsStore: BlockModelsStore);
|
|
17
|
-
getElementsCached(queriedBlock: QueriedBlock):
|
|
17
|
+
getElementsCached(queriedBlock: QueriedBlock): number | BlockElement[];
|
|
18
18
|
private resolvedModel;
|
|
19
|
-
getElements(queriedBlock: Omit<QueriedBlock, 'stateId'>, fallbackVariant?: boolean):
|
|
19
|
+
getElements(queriedBlock: Omit<QueriedBlock, 'stateId'>, fallbackVariant?: boolean): number | BlockElement[];
|
|
20
|
+
getResolvedModelByModelName(model: string, debugQueryName?: string, clearModel?: boolean): {
|
|
21
|
+
elementsOptimized: number | BlockElement[];
|
|
22
|
+
resolvedModel: Pick<BlockModel, "x" | "y" | "z" | "textures" | "ao" | "elements">;
|
|
23
|
+
} | undefined;
|
|
20
24
|
getResolvedModel(queriedBlock: Omit<QueriedBlock, 'stateId'>, fallbackVariant?: boolean): {
|
|
21
25
|
x?: number;
|
|
22
26
|
y?: number;
|
|
@@ -28,11 +32,19 @@ export declare class AssetsParser {
|
|
|
28
32
|
elements?: {
|
|
29
33
|
from: BlockElementPos;
|
|
30
34
|
to: BlockElementPos;
|
|
35
|
+
rotation?: {
|
|
36
|
+
origin: [number, number, number];
|
|
37
|
+
axis: string;
|
|
38
|
+
angle: number;
|
|
39
|
+
rescale?: boolean;
|
|
40
|
+
};
|
|
31
41
|
faces: {
|
|
32
42
|
[name: string]: {
|
|
33
43
|
texture: string;
|
|
34
44
|
uv?: number[];
|
|
35
45
|
cullface?: string;
|
|
46
|
+
rotation?: number;
|
|
47
|
+
tintindex?: number;
|
|
36
48
|
};
|
|
37
49
|
};
|
|
38
50
|
}[];
|
|
@@ -43,7 +43,6 @@ export class AssetsParser {
|
|
|
43
43
|
return properties.OR.some((or) => matchProperties(block, or));
|
|
44
44
|
}
|
|
45
45
|
for (const prop in properties) {
|
|
46
|
-
// if (properties[prop] === undefined) continue // unknown property, ignore
|
|
47
46
|
if (typeof properties[prop] !== 'string')
|
|
48
47
|
properties[prop] = String(properties[prop]);
|
|
49
48
|
if (!properties[prop].split('|').some((value) => value === String(blockProps[prop]))) {
|
|
@@ -58,7 +57,7 @@ export class AssetsParser {
|
|
|
58
57
|
return 0;
|
|
59
58
|
const states = blockStates.variants;
|
|
60
59
|
if (states) {
|
|
61
|
-
let state = states[''];
|
|
60
|
+
let state = states[''] || states['normal'];
|
|
62
61
|
for (const key in states) {
|
|
63
62
|
if (key === '')
|
|
64
63
|
continue;
|
|
@@ -95,18 +94,20 @@ export class AssetsParser {
|
|
|
95
94
|
}
|
|
96
95
|
if (!modelApply)
|
|
97
96
|
return 0;
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
// TODO losing x, y, uvlock, and not 0!
|
|
98
|
+
const model = (Array.isArray(modelApply) ? modelApply[0 /* Math.floor(Math.random() * modelApply.length) */] : modelApply).model;
|
|
99
|
+
return this.getResolvedModelByModelName(model, queriedBlock.name)?.elementsOptimized ?? 0;
|
|
100
|
+
}
|
|
101
|
+
getResolvedModelByModelName(model, debugQueryName, clearModel = true) {
|
|
102
|
+
if (clearModel) {
|
|
103
|
+
this.resolvedModel = {};
|
|
104
|
+
}
|
|
101
105
|
const modelData = this.blockModelsStore.get(this.version, model);
|
|
102
106
|
if (!modelData)
|
|
103
|
-
return
|
|
107
|
+
return;
|
|
104
108
|
// let textures = {} as Record<string, string>
|
|
105
109
|
let elements = [];
|
|
106
110
|
const resolveModel = (model) => {
|
|
107
|
-
if (model.elements) {
|
|
108
|
-
elements.push(...model.elements.map(({ from, to }) => [from, to]));
|
|
109
|
-
}
|
|
110
111
|
if (model.ambientocclusion !== undefined) {
|
|
111
112
|
this.resolvedModel.ao = model.ambientocclusion;
|
|
112
113
|
}
|
|
@@ -127,8 +128,9 @@ export class AssetsParser {
|
|
|
127
128
|
Object.assign(this.resolvedModel.textures, model.textures);
|
|
128
129
|
}
|
|
129
130
|
if (model.elements) {
|
|
131
|
+
elements.push(...model.elements.map(({ from, to }) => [from, to]));
|
|
130
132
|
this.resolvedModel.elements ??= [];
|
|
131
|
-
this.resolvedModel.elements.push(...model.elements);
|
|
133
|
+
this.resolvedModel.elements.push(...structuredClone(model.elements));
|
|
132
134
|
}
|
|
133
135
|
if (model.parent) {
|
|
134
136
|
const parent = this.blockModelsStore.get(this.version, model.parent);
|
|
@@ -147,7 +149,7 @@ export class AssetsParser {
|
|
|
147
149
|
if (!existingKey) {
|
|
148
150
|
// todo this also needs to be done at the validation stage
|
|
149
151
|
// throw new Error(`Cannot resolve texture ${key} to ${value} because it is not defined`)
|
|
150
|
-
console.warn(`${
|
|
152
|
+
console.warn(`${debugQueryName}: Cannot resolve texture ${originalTexturePath} for ${_originalKey} because it is not defined`);
|
|
151
153
|
}
|
|
152
154
|
else {
|
|
153
155
|
return existingKey;
|
|
@@ -164,7 +166,19 @@ export class AssetsParser {
|
|
|
164
166
|
else
|
|
165
167
|
delete this.resolvedModel.textures[key];
|
|
166
168
|
}
|
|
167
|
-
|
|
169
|
+
for (const elem of this.resolvedModel.elements ?? []) {
|
|
170
|
+
for (const [faceName, face] of Object.entries(elem.faces ?? {})) {
|
|
171
|
+
if (!face.texture)
|
|
172
|
+
continue;
|
|
173
|
+
// TODO validate at the validation stage
|
|
174
|
+
face.texture = this.resolvedModel.textures[face.texture.replace('#', '')] ?? face.texture;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// todo cleanup methods
|
|
178
|
+
return {
|
|
179
|
+
elementsOptimized: elements.length === 1 && arrEq(elements[0][0], [0, 0, 0]) && arrEq(elements[0][1], [16, 16, 16]) ? 1 : elements,
|
|
180
|
+
resolvedModel: this.resolvedModel,
|
|
181
|
+
};
|
|
168
182
|
}
|
|
169
183
|
getResolvedModel(queriedBlock, fallbackVariant = false) {
|
|
170
184
|
this.resolvedModel = {};
|
|
@@ -178,4 +192,3 @@ export class AssetsParser {
|
|
|
178
192
|
}
|
|
179
193
|
}
|
|
180
194
|
const arrEq = (a, b) => !!a && !!b && a.length === b.length && a.every((v, i) => v === b[i]);
|
|
181
|
-
// for each element + texture
|
package/dist/atlasCreator.js
CHANGED
|
@@ -19,6 +19,10 @@ export const getAtlasSize = (numberOfTiles, tileSize) => {
|
|
|
19
19
|
export const makeTextureAtlas = ({ input, getLoadedImage, tileSize = 16, getCanvas = () => document.createElement('canvas'), }) => {
|
|
20
20
|
const tilesCount = input.length;
|
|
21
21
|
const imgSize = getAtlasSize(tilesCount, tileSize).width;
|
|
22
|
+
const MAX_CANVAS_SIZE = 16_384;
|
|
23
|
+
if (imgSize > MAX_CANVAS_SIZE) {
|
|
24
|
+
throw new Error(`Image resolution ${imgSize} is too big, max is ${MAX_CANVAS_SIZE}x${MAX_CANVAS_SIZE}`);
|
|
25
|
+
}
|
|
22
26
|
const canvas = getCanvas(imgSize);
|
|
23
27
|
canvas.width = imgSize;
|
|
24
28
|
canvas.height = imgSize;
|
package/dist/atlasParser.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { VersionedStore } from './versionedStore';
|
|
|
2
2
|
type Texture = {
|
|
3
3
|
u: number;
|
|
4
4
|
v: number;
|
|
5
|
+
tileIndex: number;
|
|
5
6
|
su?: number;
|
|
6
7
|
sv?: number;
|
|
7
8
|
};
|
|
@@ -20,7 +21,7 @@ interface ItemsAtlases {
|
|
|
20
21
|
legacy?: ItemsAtlasesOutputJson;
|
|
21
22
|
}
|
|
22
23
|
type StoreType = Texture & {
|
|
23
|
-
|
|
24
|
+
imageType: 'latest' | 'legacy';
|
|
24
25
|
version: string;
|
|
25
26
|
};
|
|
26
27
|
type DataUrl = string;
|
|
@@ -33,17 +34,21 @@ export declare class AtlasParser {
|
|
|
33
34
|
atlasHasLegacyImage: boolean;
|
|
34
35
|
constructor(atlasJson: any, latestImage: string, legacyImage?: string | undefined);
|
|
35
36
|
get atlas(): ItemsAtlases;
|
|
36
|
-
getTextureInfo(
|
|
37
|
+
getTextureInfo(itemName: string, version?: string): {
|
|
37
38
|
su: number;
|
|
38
39
|
sv: number;
|
|
40
|
+
getLoadedImage: () => Promise<HTMLImageElement>;
|
|
39
41
|
u: number;
|
|
40
42
|
v: number;
|
|
41
|
-
|
|
43
|
+
tileIndex: number;
|
|
44
|
+
imageType: "latest" | "legacy";
|
|
42
45
|
version: string;
|
|
43
46
|
} | undefined;
|
|
44
47
|
makeNewAtlas(version: string, getCustomImage?: (itemName: string) => DataUrl | HTMLImageElement | boolean | void, tileSize?: number): Promise<{
|
|
45
48
|
canvas: HTMLCanvasElement;
|
|
46
49
|
atlas: import("./atlasCreator").JsonAtlas;
|
|
50
|
+
readonly newAtlasParser: AtlasParser;
|
|
51
|
+
readonly image: string;
|
|
47
52
|
}>;
|
|
48
53
|
}
|
|
49
54
|
export {};
|
package/dist/atlasParser.js
CHANGED
|
@@ -14,9 +14,9 @@ export class AtlasParser {
|
|
|
14
14
|
this.atlasStore = new VersionedStore();
|
|
15
15
|
this.atlasStore.inclusive = false;
|
|
16
16
|
const itemsAtlases = atlasJson;
|
|
17
|
-
const addByVersion = (store, version, textures,
|
|
17
|
+
const addByVersion = (store, version, textures, imageName) => {
|
|
18
18
|
for (const [key, path] of Object.entries(textures)) {
|
|
19
|
-
store.push(version, key, { ...path, version,
|
|
19
|
+
store.push(version, key, { ...path, version, imageType: imageName });
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
addByVersion(this.atlasStore, 'latest', itemsAtlases.latest.textures, 'latest');
|
|
@@ -31,15 +31,18 @@ export class AtlasParser {
|
|
|
31
31
|
get atlas() {
|
|
32
32
|
return this.atlasJson;
|
|
33
33
|
}
|
|
34
|
-
getTextureInfo(
|
|
34
|
+
getTextureInfo(itemName, version = 'latest') {
|
|
35
35
|
const info = this.atlasStore.get(version, itemName);
|
|
36
36
|
if (!info)
|
|
37
37
|
return;
|
|
38
|
-
const defaultSuSv = (info
|
|
38
|
+
const defaultSuSv = (info.imageType === 'latest' ? this.atlas.latest : this.atlas.legacy).suSv;
|
|
39
39
|
return {
|
|
40
40
|
...info,
|
|
41
41
|
su: info?.su ?? defaultSuSv,
|
|
42
42
|
sv: info?.sv ?? defaultSuSv,
|
|
43
|
+
getLoadedImage: async () => {
|
|
44
|
+
return await getLoadedImage(info.imageType === 'latest' ? this.latestImage : this.legacyImage);
|
|
45
|
+
}
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
48
|
async makeNewAtlas(version, getCustomImage, tileSize = this.atlas.latest.tileSize) {
|
|
@@ -62,12 +65,12 @@ export class AtlasParser {
|
|
|
62
65
|
};
|
|
63
66
|
continue;
|
|
64
67
|
}
|
|
65
|
-
const info = this.getTextureInfo(
|
|
68
|
+
const info = this.getTextureInfo(itemName, version);
|
|
66
69
|
if (!info)
|
|
67
70
|
throw new Error(`Missing texture info for ${itemName}`);
|
|
68
71
|
const { u, v, su, sv } = info;
|
|
69
72
|
const atlas = info.version === 'latest' ? itemsAtlases.latest : itemsAtlases.legacy;
|
|
70
|
-
const image = info.
|
|
73
|
+
const image = info.imageType === 'latest' ? latestImg : legacyImg;
|
|
71
74
|
if (!image)
|
|
72
75
|
throw new Error(`Missing image for ${itemName}`);
|
|
73
76
|
newTextures[itemName] = {
|
|
@@ -103,9 +106,19 @@ export class AtlasParser {
|
|
|
103
106
|
},
|
|
104
107
|
tileSize: this.atlas.latest.tileSize,
|
|
105
108
|
});
|
|
109
|
+
let _newAtlasParser;
|
|
106
110
|
return {
|
|
107
111
|
canvas,
|
|
108
|
-
atlas: json
|
|
112
|
+
atlas: json,
|
|
113
|
+
get newAtlasParser() {
|
|
114
|
+
if (!_newAtlasParser) {
|
|
115
|
+
_newAtlasParser = new AtlasParser({ latest: json }, canvas.toDataURL());
|
|
116
|
+
}
|
|
117
|
+
return _newAtlasParser;
|
|
118
|
+
},
|
|
119
|
+
get image() {
|
|
120
|
+
return canvas.toDataURL();
|
|
121
|
+
}
|
|
109
122
|
};
|
|
110
123
|
}
|
|
111
124
|
}
|