@nodecraft/rendermite 1.9.0 → 1.10.1

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.
Files changed (61) hide show
  1. package/README.md +1 -0
  2. package/dist/{block-behaviour-9Tj_GIUC.d.ts → block-behaviour-CzK3KVLx.d.ts} +46 -3
  3. package/dist/{block-behaviour-D-SG2Xfp.js → block-behaviour-DVjqeSkv.js} +26 -1
  4. package/dist/block-overrides-XtxICunI.js +77 -0
  5. package/dist/blocks/block-behaviour.d.ts +1 -1
  6. package/dist/blocks/block-behaviour.js +1 -1
  7. package/dist/blocks/block-overrides.d.ts +26 -0
  8. package/dist/blocks/block-overrides.js +2 -0
  9. package/dist/blocks/cli.js +1 -1
  10. package/dist/blocks/ender-storage.d.ts +1 -1
  11. package/dist/blocks/entities.d.ts +1 -1
  12. package/dist/blocks/entity-models.d.ts +2 -11
  13. package/dist/blocks/entity-models.js +1 -1
  14. package/dist/blocks/entity-sizes.js +1 -1
  15. package/dist/blocks/export.d.ts +1 -1
  16. package/dist/blocks/export.js +1 -1
  17. package/dist/blocks/game-rules.js +1 -1
  18. package/dist/blocks/geo-blocks.d.ts +1 -1
  19. package/dist/blocks/item-sprites.d.ts +1 -1
  20. package/dist/blocks/light-bytecode.d.ts +1 -1
  21. package/dist/blocks/light-bytecode.js +1 -1
  22. package/dist/blocks/light-eval.d.ts +1 -1
  23. package/dist/blocks/light.d.ts +3 -1
  24. package/dist/blocks/light.js +1 -1
  25. package/dist/blocks/names.d.ts +2 -0
  26. package/dist/blocks/names.js +2 -0
  27. package/dist/blocks/pack-format.d.ts +2 -2
  28. package/dist/blocks/sprite-sheet.d.ts +1 -1
  29. package/dist/{classfile-CiIDF3vc.js → classfile-BJSs3JH0.js} +23 -3
  30. package/dist/{classfile-CsLXlh5z.d.ts → classfile-Dzn0gW9M.d.ts} +6 -0
  31. package/dist/{cli-xBcMuKA3.js → cli-2mzPC8cy.js} +1 -1
  32. package/dist/cli.js +1 -1
  33. package/dist/entities/classfile.d.ts +1 -1
  34. package/dist/entities/classfile.js +1 -1
  35. package/dist/entities/inherit.d.ts +2 -2
  36. package/dist/entities/inherit.js +1 -1
  37. package/dist/entities/link.d.ts +1 -1
  38. package/dist/entities/link.js +1 -1
  39. package/dist/entities/model-bytecode.d.ts +1 -1
  40. package/dist/entities/model-bytecode.js +1 -1
  41. package/dist/entities/model-code.d.ts +1 -1
  42. package/dist/entities/model-code.js +1 -1
  43. package/dist/{entity-models-BYAxrTsk.js → entity-models-vFl_EwfA.js} +23 -4
  44. package/dist/{entity-sizes-CpO1gA7p.js → entity-sizes-DspxgSUA.js} +1 -1
  45. package/dist/{export-HEoqcV-Y.d.ts → export-CqeTinYL.d.ts} +2 -0
  46. package/dist/{export-CbG2Rx3i.js → export-DgB0e5sB.js} +14 -5
  47. package/dist/{game-rules-DuLlFc7o.js → game-rules-BDPTopVW.js} +2 -2
  48. package/dist/index.d.ts +1 -1
  49. package/dist/index.js +1 -1
  50. package/dist/{inherit-BUn0Cve9.js → inherit-DJ45bOB_.js} +2 -2
  51. package/dist/{light-CC3VMsjl.js → light-BnaYFouC.js} +15 -4
  52. package/dist/{light-bytecode-DYxb6pJk.js → light-bytecode-hhkkjMVi.js} +110 -23
  53. package/dist/{light-eval-DMjK6xnb.d.ts → light-eval-B4q-aVcf.d.ts} +1 -1
  54. package/dist/{link-Cuhyrz07.js → link-IDjVJ2Ij.js} +1 -1
  55. package/dist/{model-bytecode-VaLUQfGO.js → model-bytecode-CXYAZ5dX.js} +1 -1
  56. package/dist/{model-code-Csc3bs3h.d.ts → model-code-BclYt1do.d.ts} +1 -1
  57. package/dist/{model-code-DbN2uVhp.js → model-code-BmA5ilgt.js} +1 -1
  58. package/dist/names-D1abAVIB.d.ts +10 -0
  59. package/dist/names-GLa5TyL7.js +36 -0
  60. package/dist/pack.d.ts +3 -3
  61. package/package.json +1 -1
package/README.md CHANGED
@@ -84,6 +84,7 @@ blocks/1.21.8/
84
84
  tags.json # the version's own tags, every registry, unexpanded
85
85
  advancements.json # each advancement's criteria
86
86
  game-rules.json # every game rule with its type and default
87
+ names.json # block and item display names from the lang files
87
88
  states.json # every property and default state (with --reports <data generator reports>)
88
89
  failures.json # anything not fully handled, with reasons, never silent
89
90
  meta.json # version, counts, sha256 of every other file
@@ -2,11 +2,12 @@ import { n as BiomeClimatePack } from "./biomes-CnnhDCnk.js";
2
2
  import { a as BlockStateMultipartCase, o as BlockStateVariantCase } from "./blockstate-eval-BzznRcVY.js";
3
3
  import { r as TagPack, t as AdvancementPack } from "./datapack-CmEg0Vko.js";
4
4
  import { n as GameRulePack } from "./game-rules-ThvdDG3B.js";
5
+ import { t as NamePack } from "./names-D1abAVIB.js";
5
6
  import { a as FaceDirectionName, l as Vec3, o as ModelElementJson, u as Vec4 } from "./types-qlp3I8_-.js";
6
7
  import { t as MeshGroup } from "./obj-mesh-CzL0lOlJ.js";
7
8
  import { n as BlockStatesPack } from "./states-OzneeCTU.js";
8
9
  import { n as BlockTintPack } from "./tints-DwFmEkf3.js";
9
- import { t as ClassFile } from "./classfile-CsLXlh5z.js";
10
+ import { t as ClassFile } from "./classfile-Dzn0gW9M.js";
10
11
  //#region src/blocks/pack-format.d.ts
11
12
  /** How a sprite's alpha classifies it, inferred because assets rarely say. */
12
13
  type BlockPackRenderLayer = 'solid' | 'cutout' | 'translucent';
@@ -167,6 +168,8 @@ type BlockPackStatesFile = BlockStatesPack;
167
168
  * (camelCase before 26.x, snake_case from it), with its type and default. Vanilla packs only.
168
169
  */
169
170
  type BlockPackGameRulesFile = GameRulePack;
171
+ /** `names.json`: English display names by id, for blocks and items, from each namespace's `en_us`. */
172
+ type BlockPackNamesFile = NamePack;
170
173
  /** One flat sprite of an item's layer stack, in the order the client draws them. */
171
174
  interface ItemPackLayer {
172
175
  sprite: string;
@@ -347,6 +350,8 @@ interface EquipmentPack {
347
350
  }>;
348
351
  /** Materials whose sheet is greyscale and takes the item's own dye colour. */
349
352
  dyeable: string[];
353
+ /** The colour a dyeable material takes when nothing dyed it, read from the game's own constant. */
354
+ undyed?: Record<string, string>;
350
355
  /** Worn armour-trim sheets generated from the version's armour-trim atlas. */
351
356
  trims: {
352
357
  /** Sprite ids per pattern and material, into this file's own `sprites`. */
@@ -385,6 +390,8 @@ interface BlockPackMetaFile {
385
390
  states: number;
386
391
  /** Rules in `game-rules.json`; `0` means the file is absent. */
387
392
  gameRules: number;
393
+ /** Block and item names in `names.json`; `0` means the file is absent. */
394
+ names: number;
388
395
  failures: number;
389
396
  };
390
397
  /** sha256 per file, enough to verify a cached copy without refetching it. */
@@ -413,6 +420,8 @@ interface LightCodeSource {
413
420
  * Absent, or answering the name it was given, where the jar already speaks original names.
414
421
  */
415
422
  nameOf?: (reference: MemberReference, field: boolean) => string;
423
+ /** A block's default state by full id, from the data generator's report when the export has one. */
424
+ defaultStateOf?: (blockId: string) => Readonly<Record<string, string>> | null;
416
425
  /** Classes that are a block `Properties` builder, in every spelling the jars use. */
417
426
  propsClasses: ReadonlySet<string>;
418
427
  /**
@@ -575,6 +584,12 @@ interface LightExtraction {
575
584
  } | {
576
585
  failure: string;
577
586
  };
587
+ /** The same, for a method a block's class declares, run on the block its registration made. */
588
+ tabulateMethod: (registration: Registration, method: MemberReference, read: (value: Value) => number | null) => {
589
+ value: BlockPackLight;
590
+ } | {
591
+ failure: string;
592
+ };
578
593
  /** What was recorded for a block, for a person chasing a failure. */
579
594
  describe: (blockId: string) => string;
580
595
  }
@@ -618,15 +633,43 @@ interface BlockBehaviour {
618
633
  friction?: number;
619
634
  speedFactor?: number;
620
635
  jumpFactor?: number;
636
+ /**
637
+ * The block's shape decides how light crosses its faces (`useShapeForLightOcclusion`): stairs,
638
+ * slabs, snow layers. `true` in every state, or cases of 1 where a state does (a double slab does not).
639
+ */
640
+ lightShape?: true | Exclude<BlockPackLight, number>;
641
+ /**
642
+ * Light lost passing through the block, where its class answers for itself (`getLightBlock`): 15
643
+ * for tinted glass, whose faces are see-through. Absent means the game's default rule.
644
+ */
645
+ lightBlock?: BlockPackLight;
646
+ /** The fluid the block holds in every state, as kelp and seagrass are always under water. */
647
+ fluid?: 'water' | 'lava';
648
+ /**
649
+ * The block model renderer draws nothing for it (`RenderShape.INVISIBLE`): a barrier, a light block, a
650
+ * structure void, and the blocks something else draws, a fluid or an end portal.
651
+ */
652
+ invisible?: true;
653
+ /**
654
+ * Its class decides whether a face against a neighbour draws (`skipRendering`): glass hides the faces
655
+ * it shares with glass, although its texture reads as plain cutout.
656
+ */
657
+ hidesSharedFaces?: true;
621
658
  }
622
659
  /**
623
660
  * The colour a block's `Properties` state: a `mapColor` call, the colour a pre-1.20 `Properties` was
624
661
  * constructed with, or its `Material`'s, latest first. A constant or a function of state.
625
662
  */
626
663
  declare function statedMapColor(props: Handle): Value | undefined;
627
- declare function blockBehaviour(registration: Registration, extraction: Pick<LightExtraction, 'tabulate'>): {
664
+ declare function blockBehaviour(registration: Registration, extraction: Pick<LightExtraction, 'tabulate' | 'tabulateMethod'>,
665
+ /** The block's class's overrides, if it can be read: see `block-overrides.ts`. */
666
+ overrides?: {
667
+ of: (names: readonly string[]) => MemberReference | null;
668
+ fluid: (method: MemberReference) => 'water' | 'lava' | null;
669
+ invisible: (method: MemberReference) => boolean;
670
+ } | null): {
628
671
  behaviour: BlockBehaviour;
629
672
  failures: string[];
630
673
  } | null;
631
674
  //#endregion
632
- export { BlockPackItemsFile as A, BlockPackTagsFile as B, BlockPackBlockState as C, BlockPackEntityModelsFile as D, BlockPackEntitiesFile as E, BlockPackModelsFile as F, EntityPackCubeFace as G, BlockPackVariant as H, BlockPackRenderLayer as I, EntityPackPart as J, EntityPackEntry as K, BlockPackSprite as L, BlockPackLightFile as M, BlockPackMetaFile as N, BlockPackFace as O, BlockPackModel as P, ItemPackLayer as Q, BlockPackSpriteFrame as R, BlockPackBiomesFile as S, BlockPackElement as T, EQUIPMENT_SLOTS as U, BlockPackTintsFile as V, EntityPackCube as W, EquipmentSlot as X, EquipmentPack as Y, ItemPackEntry as Z, extractBlockLight as _, Handle as a, BlockPackAtlasPage as b, LightExtraction as c, MemberReference as d, PropertyDomain as f, Value as g, StateProbe as h, statedMapColor as i, BlockPackLight as j, BlockPackGameRulesFile as k, LightGetter as l, Registration as m, PushReactionName as n, LambdaValue as o, PropsCall as p, EntityPackModel as q, blockBehaviour as r, LightCodeSource as s, BlockBehaviour as t, LightSpec as u, BlockPackAdvancementsFile as v, BlockPackBlockStatesFile as w, BlockPackBehaviourFile as x, BlockPackAtlasFile as y, BlockPackStatesFile as z };
675
+ export { ItemPackLayer as $, BlockPackItemsFile as A, BlockPackStatesFile as B, BlockPackBlockState as C, BlockPackEntityModelsFile as D, BlockPackEntitiesFile as E, BlockPackModelsFile as F, EntityPackCube as G, BlockPackTintsFile as H, BlockPackNamesFile as I, EntityPackModel as J, EntityPackCubeFace as K, BlockPackRenderLayer as L, BlockPackLightFile as M, BlockPackMetaFile as N, BlockPackFace as O, BlockPackModel as P, ItemPackEntry as Q, BlockPackSprite as R, BlockPackBiomesFile as S, BlockPackElement as T, BlockPackVariant as U, BlockPackTagsFile as V, EQUIPMENT_SLOTS as W, EquipmentPack as X, EntityPackPart as Y, EquipmentSlot as Z, extractBlockLight as _, Handle as a, BlockPackAtlasPage as b, LightExtraction as c, MemberReference as d, PropertyDomain as f, Value as g, StateProbe as h, statedMapColor as i, BlockPackLight as j, BlockPackGameRulesFile as k, LightGetter as l, Registration as m, PushReactionName as n, LambdaValue as o, PropsCall as p, EntityPackEntry as q, blockBehaviour as r, LightCodeSource as s, BlockBehaviour as t, LightSpec as u, BlockPackAdvancementsFile as v, BlockPackBlockStatesFile as w, BlockPackBehaviourFile as x, BlockPackAtlasFile as y, BlockPackSpriteFrame as z };
@@ -61,7 +61,10 @@ function float32(value) {
61
61
  }
62
62
  return value;
63
63
  }
64
- function blockBehaviour(registration, extraction) {
64
+ function flag(value) {
65
+ return value.kind === "number" ? value.value === 0 ? 0 : 1 : null;
66
+ }
67
+ function blockBehaviour(registration, extraction, overrides = null) {
65
68
  const props = registration.props;
66
69
  if (!props) return null;
67
70
  const failures = [];
@@ -146,6 +149,28 @@ function blockBehaviour(registration, extraction) {
146
149
  if (id === null) failures.push("map colour is a value the interpreter could not identify");
147
150
  else behaviour.mapColor = id;
148
151
  }
152
+ const answer = (names, read) => {
153
+ const method = overrides?.of(names) ?? null;
154
+ if (!method) return null;
155
+ const folded = extraction.tabulateMethod(registration, method, read);
156
+ if ("failure" in folded) {
157
+ failures.push(`${names[0]}: ${folded.failure}`);
158
+ return null;
159
+ }
160
+ return folded.value;
161
+ };
162
+ const shape = answer(["useShapeForLightOcclusion"], flag);
163
+ if (shape === 1) behaviour.lightShape = true;
164
+ else if (shape !== null && typeof shape === "object") behaviour.lightShape = shape;
165
+ const lightBlock = answer(["getLightBlock", "getLightDampening"], (value) => value.kind === "number" ? value.value : null);
166
+ if (lightBlock !== null) behaviour.lightBlock = lightBlock;
167
+ const fluidMethod = overrides?.of(["getFluidState"]);
168
+ const fluid = fluidMethod && overrides ? overrides.fluid(fluidMethod) : null;
169
+ if (fluid) behaviour.fluid = fluid;
170
+ const renderShape = overrides?.of(["getRenderShape"]);
171
+ if (renderShape && overrides?.invisible(renderShape)) behaviour.invisible = true;
172
+ if (overrides?.of(["skipRendering"])) behaviour.hidesSharedFaces = true;
173
+ if (answer(["isAir"], flag) === 1) behaviour.air = true;
149
174
  return {
150
175
  behaviour,
151
176
  failures
@@ -0,0 +1,77 @@
1
+ import { n as instructions } from "./entity-sizes-DspxgSUA.js";
2
+ //#region src/blocks/block-overrides.ts
3
+ /**
4
+ * Where a block's own class answers a question itself, rather than leaving it to its `Properties`.
5
+ *
6
+ * Some of what a block does is a method override, not a builder call: a stair or a slab tests its
7
+ * shape for light (`useShapeForLightOcclusion`), tinted glass stops all light (`getLightBlock`), kelp is
8
+ * always under water (`getFluidState`), and before 1.16.2 an air block said so by overriding `isAir`.
9
+ * The override is found by walking the block's class chain for a method of that original name, and it
10
+ * only counts where a class below the base declares it: the base's own is the default answer.
11
+ */
12
+ /** `getstatic`, `invokevirtual` and `invokeinterface`: the instructions whose target says what code reads. */
13
+ const READS = /* @__PURE__ */ new Set([
14
+ 178,
15
+ 182,
16
+ 185
17
+ ]);
18
+ /** How far up a block's class chain to look; vanilla's deepest is well under this. */
19
+ const MAX_DEPTH = 16;
20
+ /** The nearest override of one of `names` above `blockType`, or null where only the base declares it. */
21
+ function overrideOf(source, blockType, names) {
22
+ const declarations = [];
23
+ let at = source.resolve(blockType);
24
+ for (let depth = 0; at && depth < MAX_DEPTH; depth++) {
25
+ const owner = at.thisClass;
26
+ const method = at.methods.find((candidate) => candidate.code && names.includes(source.nameOf({
27
+ owner,
28
+ name: candidate.name,
29
+ descriptor: candidate.descriptor
30
+ }, false)));
31
+ if (method) declarations.push({
32
+ owner,
33
+ name: method.name,
34
+ descriptor: method.descriptor
35
+ });
36
+ at = at.superClass ? source.resolve(at.superClass) : null;
37
+ }
38
+ return declarations.length > 1 ? declarations[0] : null;
39
+ }
40
+ /**
41
+ * The constants an override reads, by original name, and whether it reads a block property: enough to
42
+ * answer from its code without running it. Kelp's `getFluidState` reads `Fluids.WATER` and nothing
43
+ * else; a barrier's `getRenderShape` reads `RenderShape.INVISIBLE`. One that reads a property
44
+ * (`waterlogged`) answers per state, which the state already says.
45
+ */
46
+ function constantsReadBy(source, method) {
47
+ const classFile = source.resolve(method.owner);
48
+ const code = classFile?.methods.find((candidate) => candidate.name === method.name && candidate.descriptor === method.descriptor)?.code;
49
+ if (!classFile || !code) return null;
50
+ const statics = /* @__PURE__ */ new Set();
51
+ let readsState = false;
52
+ for (const { op, index } of instructions(code)) {
53
+ const reference = READS.has(op) ? classFile.reference(index) : null;
54
+ if (!reference) continue;
55
+ const name = source.nameOf(reference, op === 178);
56
+ if (op === 178) statics.add(name);
57
+ else if (name === "getValue") readsState = true;
58
+ }
59
+ return {
60
+ statics,
61
+ readsState
62
+ };
63
+ }
64
+ /** The fluid an override of `getFluidState` holds in every state, or null where it depends on one. */
65
+ function constantFluidOf(source, method) {
66
+ const read = constantsReadBy(source, method);
67
+ if (!read || read.readsState) return null;
68
+ if (read.statics.has("WATER")) return "water";
69
+ return read.statics.has("LAVA") ? "lava" : null;
70
+ }
71
+ /** Whether an override of `getRenderShape` always answers `INVISIBLE`, as a barrier's and a light block's do. */
72
+ function alwaysInvisible(source, method) {
73
+ const read = constantsReadBy(source, method);
74
+ return read !== null && !read.readsState && read.statics.has("INVISIBLE") && !read.statics.has("MODEL");
75
+ }
76
+ //#endregion
77
+ export { overrideOf as i, constantFluidOf as n, constantsReadBy as r, alwaysInvisible as t };
@@ -1,2 +1,2 @@
1
- import { i as statedMapColor, n as PushReactionName, r as blockBehaviour, t as BlockBehaviour } from "../block-behaviour-9Tj_GIUC.js";
1
+ import { i as statedMapColor, n as PushReactionName, r as blockBehaviour, t as BlockBehaviour } from "../block-behaviour-CzK3KVLx.js";
2
2
  export { BlockBehaviour, PushReactionName, blockBehaviour, statedMapColor };
@@ -1,2 +1,2 @@
1
- import { n as statedMapColor, t as blockBehaviour } from "../block-behaviour-D-SG2Xfp.js";
1
+ import { n as statedMapColor, t as blockBehaviour } from "../block-behaviour-DVjqeSkv.js";
2
2
  export { blockBehaviour, statedMapColor };
@@ -0,0 +1,26 @@
1
+ import { d as MemberReference } from "../block-behaviour-CzK3KVLx.js";
2
+ import { t as ClassFile } from "../classfile-Dzn0gW9M.js";
3
+ //#region src/blocks/block-overrides.d.ts
4
+ interface OverrideSource {
5
+ resolve: (internalName: string) => ClassFile | null;
6
+ /** A member's original name, for a jar that spells the game's own obfuscated. */
7
+ nameOf: (reference: MemberReference, field: boolean) => string;
8
+ }
9
+ /** The nearest override of one of `names` above `blockType`, or null where only the base declares it. */
10
+ declare function overrideOf(source: OverrideSource, blockType: string, names: readonly string[]): MemberReference | null;
11
+ /**
12
+ * The constants an override reads, by original name, and whether it reads a block property: enough to
13
+ * answer from its code without running it. Kelp's `getFluidState` reads `Fluids.WATER` and nothing
14
+ * else; a barrier's `getRenderShape` reads `RenderShape.INVISIBLE`. One that reads a property
15
+ * (`waterlogged`) answers per state, which the state already says.
16
+ */
17
+ declare function constantsReadBy(source: OverrideSource, method: MemberReference): {
18
+ statics: Set<string>;
19
+ readsState: boolean;
20
+ } | null;
21
+ /** The fluid an override of `getFluidState` holds in every state, or null where it depends on one. */
22
+ declare function constantFluidOf(source: OverrideSource, method: MemberReference): 'water' | 'lava' | null;
23
+ /** Whether an override of `getRenderShape` always answers `INVISIBLE`, as a barrier's and a light block's do. */
24
+ declare function alwaysInvisible(source: OverrideSource, method: MemberReference): boolean;
25
+ //#endregion
26
+ export { OverrideSource, alwaysInvisible, constantFluidOf, constantsReadBy, overrideOf };
@@ -0,0 +1,2 @@
1
+ import { i as overrideOf, n as constantFluidOf, r as constantsReadBy, t as alwaysInvisible } from "../block-overrides-XtxICunI.js";
2
+ export { alwaysInvisible, constantFluidOf, constantsReadBy, overrideOf };
@@ -1,2 +1,2 @@
1
- import { t as runBlocksCli } from "../cli-xBcMuKA3.js";
1
+ import { t as runBlocksCli } from "../cli-2mzPC8cy.js";
2
2
  export { runBlocksCli };
@@ -1,5 +1,5 @@
1
1
  import { a as ResourceManager } from "../manager-Ct0dEOMg.js";
2
- import { P as BlockPackModel } from "../block-behaviour-9Tj_GIUC.js";
2
+ import { P as BlockPackModel } from "../block-behaviour-CzK3KVLx.js";
3
3
  //#region src/blocks/ender-storage.d.ts
4
4
  /**
5
5
  * Ender Storage feeds this OBJ through CodeChickenLib's `swapYZ`, translates it almost exactly onto
@@ -1,6 +1,6 @@
1
1
  import { a as ResourceManager } from "../manager-Ct0dEOMg.js";
2
2
  import { i as TextureLoader } from "../loader-C4gsX_wO.js";
3
- import { K as EntityPackEntry } from "../block-behaviour-9Tj_GIUC.js";
3
+ import { q as EntityPackEntry } from "../block-behaviour-CzK3KVLx.js";
4
4
  //#region src/blocks/entities.d.ts
5
5
  interface EntityPackResult {
6
6
  entities: Record<string, EntityPackEntry>;
@@ -1,8 +1,8 @@
1
1
  import { a as ResourceManager } from "../manager-Ct0dEOMg.js";
2
2
  import { t as ClassSource } from "../jar-classes-CSRrPAUy.js";
3
- import { Y as EquipmentPack, q as EntityPackModel } from "../block-behaviour-9Tj_GIUC.js";
3
+ import { J as EntityPackModel, X as EquipmentPack } from "../block-behaviour-CzK3KVLx.js";
4
4
  import { t as Mappings } from "../mappings-DhOPQTgV.js";
5
- import { t as ModelCode } from "../model-code-Csc3bs3h.js";
5
+ import { t as ModelCode } from "../model-code-BclYt1do.js";
6
6
  //#region src/blocks/entity-models.d.ts
7
7
  interface EntityGeometryResult {
8
8
  /** Model id (the class it came from) → geometry. */
@@ -53,15 +53,6 @@ declare function collectEntityGeometry(options: CollectEntityGeometryOptions): P
53
53
  * lowest to highest precedence, matching atlas source resolution when packs extend the vanilla file.
54
54
  */
55
55
  declare function collectArmourTrims(resources: ResourceManager, spriteIds: Set<string>): Promise<EquipmentPack['trims']>;
56
- /**
57
- * Worn armour for the pack: one humanoid mesh, the sheets each material is drawn with, and which
58
- * item is which.
59
- *
60
- * Materials are discovered from the sheets the version actually ships rather than listed, so a
61
- * version that adds one — copper, in the 26 line — needs no edit here. The item ids are the one part
62
- * the assets cannot answer, since nothing in them maps `iron_helmet` to `iron`: they follow the
63
- * game's own naming, and each is confirmed against a real item model before being claimed.
64
- */
65
56
  declare function collectEquipment(names: readonly string[], mappings: Mappings, read: (internal: string) => Promise<Uint8Array | null>, code: ModelCode, resources: ResourceManager | undefined, models: Record<string, EntityPackModel>, spriteIds: Set<string>): Promise<EquipmentPack | null>;
66
57
  //#endregion
67
58
  export { CollectEntityGeometryOptions, EntityGeometryResult, collectArmourTrims, collectEntityGeometry, collectEquipment };
@@ -1,2 +1,2 @@
1
- import { n as collectEntityGeometry, r as collectEquipment, t as collectArmourTrims } from "../entity-models-BYAxrTsk.js";
1
+ import { n as collectEntityGeometry, r as collectEquipment, t as collectArmourTrims } from "../entity-models-vFl_EwfA.js";
2
2
  export { collectArmourTrims, collectEntityGeometry, collectEquipment };
@@ -1,2 +1,2 @@
1
- import { n as instructions, t as collectEntitySizes } from "../entity-sizes-CpO1gA7p.js";
1
+ import { n as instructions, t as collectEntitySizes } from "../entity-sizes-DspxgSUA.js";
2
2
  export { collectEntitySizes, instructions };
@@ -1,2 +1,2 @@
1
- import { i as exportBlockPack, n as BlockPackResult, r as ExportBlockPackOptions, t as BlockPackFailure } from "../export-HEoqcV-Y.js";
1
+ import { i as exportBlockPack, n as BlockPackResult, r as ExportBlockPackOptions, t as BlockPackFailure } from "../export-CqeTinYL.js";
2
2
  export { BlockPackFailure, BlockPackResult, ExportBlockPackOptions, exportBlockPack };
@@ -1,2 +1,2 @@
1
- import { t as exportBlockPack } from "../export-CbG2Rx3i.js";
1
+ import { t as exportBlockPack } from "../export-DgB0e5sB.js";
2
2
  export { exportBlockPack };
@@ -1,2 +1,2 @@
1
- import { t as collectGameRules } from "../game-rules-DuLlFc7o.js";
1
+ import { t as collectGameRules } from "../game-rules-BDPTopVW.js";
2
2
  export { collectGameRules };
@@ -1,5 +1,5 @@
1
1
  import { a as ResourceManager } from "../manager-Ct0dEOMg.js";
2
- import { P as BlockPackModel } from "../block-behaviour-9Tj_GIUC.js";
2
+ import { P as BlockPackModel } from "../block-behaviour-CzK3KVLx.js";
3
3
  //#region src/blocks/geo-blocks.d.ts
4
4
  interface GeoBlockOverride {
5
5
  model: BlockPackModel;
@@ -1,7 +1,7 @@
1
1
  import { a as ResourceManager } from "../manager-Ct0dEOMg.js";
2
2
  import { i as TextureLoader } from "../loader-C4gsX_wO.js";
3
3
  import { t as ModelLoader } from "../loader-BYyPIs9f.js";
4
- import { Z as ItemPackEntry } from "../block-behaviour-9Tj_GIUC.js";
4
+ import { Q as ItemPackEntry } from "../block-behaviour-CzK3KVLx.js";
5
5
  //#region src/blocks/item-sprites.d.ts
6
6
  interface ItemSpriteFailure {
7
7
  id: string;
@@ -1,2 +1,2 @@
1
- import { _ as extractBlockLight, a as Handle, c as LightExtraction, d as MemberReference, f as PropertyDomain, g as Value, h as StateProbe, l as LightGetter, m as Registration, o as LambdaValue, p as PropsCall, s as LightCodeSource, u as LightSpec } from "../block-behaviour-9Tj_GIUC.js";
1
+ import { _ as extractBlockLight, a as Handle, c as LightExtraction, d as MemberReference, f as PropertyDomain, g as Value, h as StateProbe, l as LightGetter, m as Registration, o as LambdaValue, p as PropsCall, s as LightCodeSource, u as LightSpec } from "../block-behaviour-CzK3KVLx.js";
2
2
  export { Handle, LambdaValue, LightCodeSource, LightExtraction, LightGetter, LightSpec, MemberReference, PropertyDomain, PropsCall, Registration, StateProbe, Value, extractBlockLight };
@@ -1,2 +1,2 @@
1
- import { t as extractBlockLight } from "../light-bytecode-DYxb6pJk.js";
1
+ import { t as extractBlockLight } from "../light-bytecode-hhkkjMVi.js";
2
2
  export { extractBlockLight };
@@ -1,2 +1,2 @@
1
- import { t as blockLightLevel } from "../light-eval-DMjK6xnb.js";
1
+ import { t as blockLightLevel } from "../light-eval-B4q-aVcf.js";
2
2
  export { blockLightLevel };
@@ -1,5 +1,5 @@
1
1
  import { t as ClassSource } from "../jar-classes-CSRrPAUy.js";
2
- import { j as BlockPackLight, t as BlockBehaviour } from "../block-behaviour-9Tj_GIUC.js";
2
+ import { j as BlockPackLight, t as BlockBehaviour } from "../block-behaviour-CzK3KVLx.js";
3
3
  //#region src/blocks/light.d.ts
4
4
  interface CollectBlockLightOptions {
5
5
  version: string;
@@ -8,6 +8,8 @@ interface CollectBlockLightOptions {
8
8
  classes: ClassSource;
9
9
  /** Every block the pack describes, fully qualified; each gets an answer or a failure. */
10
10
  blockIds: readonly string[];
11
+ /** A block's default state, from the data generator's report, for a colour that is a function of state. */
12
+ defaultStateOf?: (blockId: string) => Readonly<Record<string, string>> | null;
11
13
  /** Blocks to describe in `notes` — what was registered and with which light — for chasing a failure. */
12
14
  trace?: readonly string[];
13
15
  onProgress?: (done: number, total: number) => void;
@@ -1,2 +1,2 @@
1
- import { n as collectBlockLight, r as vanillaLightAt, t as VANILLA_LIGHT } from "../light-CC3VMsjl.js";
1
+ import { n as collectBlockLight, r as vanillaLightAt, t as VANILLA_LIGHT } from "../light-BnaYFouC.js";
2
2
  export { VANILLA_LIGHT, collectBlockLight, vanillaLightAt };
@@ -0,0 +1,2 @@
1
+ import { n as collectNames, t as NamePack } from "../names-D1abAVIB.js";
2
+ export { NamePack, collectNames };
@@ -0,0 +1,2 @@
1
+ import { t as collectNames } from "../names-GLa5TyL7.js";
2
+ export { collectNames };
@@ -1,2 +1,2 @@
1
- import { A as BlockPackItemsFile, B as BlockPackTagsFile, C as BlockPackBlockState, D as BlockPackEntityModelsFile, E as BlockPackEntitiesFile, F as BlockPackModelsFile, G as EntityPackCubeFace, H as BlockPackVariant, I as BlockPackRenderLayer, J as EntityPackPart, K as EntityPackEntry, L as BlockPackSprite, M as BlockPackLightFile, N as BlockPackMetaFile, O as BlockPackFace, P as BlockPackModel, Q as ItemPackLayer, R as BlockPackSpriteFrame, S as BlockPackBiomesFile, T as BlockPackElement, U as EQUIPMENT_SLOTS, V as BlockPackTintsFile, W as EntityPackCube, X as EquipmentSlot, Y as EquipmentPack, Z as ItemPackEntry, b as BlockPackAtlasPage, j as BlockPackLight, k as BlockPackGameRulesFile, q as EntityPackModel, v as BlockPackAdvancementsFile, w as BlockPackBlockStatesFile, x as BlockPackBehaviourFile, y as BlockPackAtlasFile, z as BlockPackStatesFile } from "../block-behaviour-9Tj_GIUC.js";
2
- export { BlockPackAdvancementsFile, BlockPackAtlasFile, BlockPackAtlasPage, BlockPackBehaviourFile, BlockPackBiomesFile, BlockPackBlockState, BlockPackBlockStatesFile, BlockPackElement, BlockPackEntitiesFile, BlockPackEntityModelsFile, BlockPackFace, BlockPackGameRulesFile, BlockPackItemsFile, BlockPackLight, BlockPackLightFile, BlockPackMetaFile, BlockPackModel, BlockPackModelsFile, BlockPackRenderLayer, BlockPackSprite, BlockPackSpriteFrame, BlockPackStatesFile, BlockPackTagsFile, BlockPackTintsFile, BlockPackVariant, EQUIPMENT_SLOTS, EntityPackCube, EntityPackCubeFace, EntityPackEntry, EntityPackModel, EntityPackPart, EquipmentPack, EquipmentSlot, ItemPackEntry, ItemPackLayer };
1
+ import { $ as ItemPackLayer, A as BlockPackItemsFile, B as BlockPackStatesFile, C as BlockPackBlockState, D as BlockPackEntityModelsFile, E as BlockPackEntitiesFile, F as BlockPackModelsFile, G as EntityPackCube, H as BlockPackTintsFile, I as BlockPackNamesFile, J as EntityPackModel, K as EntityPackCubeFace, L as BlockPackRenderLayer, M as BlockPackLightFile, N as BlockPackMetaFile, O as BlockPackFace, P as BlockPackModel, Q as ItemPackEntry, R as BlockPackSprite, S as BlockPackBiomesFile, T as BlockPackElement, U as BlockPackVariant, V as BlockPackTagsFile, W as EQUIPMENT_SLOTS, X as EquipmentPack, Y as EntityPackPart, Z as EquipmentSlot, b as BlockPackAtlasPage, j as BlockPackLight, k as BlockPackGameRulesFile, q as EntityPackEntry, v as BlockPackAdvancementsFile, w as BlockPackBlockStatesFile, x as BlockPackBehaviourFile, y as BlockPackAtlasFile, z as BlockPackSpriteFrame } from "../block-behaviour-CzK3KVLx.js";
2
+ export { BlockPackAdvancementsFile, BlockPackAtlasFile, BlockPackAtlasPage, BlockPackBehaviourFile, BlockPackBiomesFile, BlockPackBlockState, BlockPackBlockStatesFile, BlockPackElement, BlockPackEntitiesFile, BlockPackEntityModelsFile, BlockPackFace, BlockPackGameRulesFile, BlockPackItemsFile, BlockPackLight, BlockPackLightFile, BlockPackMetaFile, BlockPackModel, BlockPackModelsFile, BlockPackNamesFile, BlockPackRenderLayer, BlockPackSprite, BlockPackSpriteFrame, BlockPackStatesFile, BlockPackTagsFile, BlockPackTintsFile, BlockPackVariant, EQUIPMENT_SLOTS, EntityPackCube, EntityPackCubeFace, EntityPackEntry, EntityPackModel, EntityPackPart, EquipmentPack, EquipmentSlot, ItemPackEntry, ItemPackLayer };
@@ -1,6 +1,6 @@
1
1
  import { i as TextureLoader, r as Texture } from "../loader-C4gsX_wO.js";
2
2
  import { i as PackedPage } from "../atlas-pack-BUadroKy.js";
3
- import { I as BlockPackRenderLayer, L as BlockPackSprite } from "../block-behaviour-9Tj_GIUC.js";
3
+ import { L as BlockPackRenderLayer, R as BlockPackSprite } from "../block-behaviour-CzK3KVLx.js";
4
4
  //#region src/blocks/sprite-sheet.d.ts
5
5
  /**
6
6
  * Vanilla's own id for the missing-texture sprite. A face whose texture does
@@ -173,7 +173,7 @@ function readConstantPool(reader) {
173
173
  * Skips an attribute table, keeping the two that say what a method does: `Code`, and the class-level
174
174
  * `BootstrapMethods` that a lambda's real body is reachable through.
175
175
  */
176
- function readAttributes(reader, utf8, bootstraps) {
176
+ function readAttributes(reader, utf8, bootstraps, constants) {
177
177
  let code;
178
178
  const count = reader.u2();
179
179
  for (let index = 0; index < count; index++) {
@@ -193,6 +193,10 @@ function readAttributes(reader, utf8, bootstraps) {
193
193
  }
194
194
  continue;
195
195
  }
196
+ if (name === "ConstantValue" && constants) {
197
+ constants.push(reader.u2());
198
+ continue;
199
+ }
196
200
  if (name !== "Code") {
197
201
  reader.skip(length);
198
202
  continue;
@@ -221,10 +225,19 @@ function parseClassFile(bytes) {
221
225
  const superIndex = reader.u2();
222
226
  const superClass = superIndex === 0 ? null : utf8(superIndex);
223
227
  reader.skip(reader.u2() * 2);
228
+ const fieldEntries = [];
224
229
  const fieldCount = reader.u2();
225
230
  for (let index = 0; index < fieldCount; index++) {
226
- reader.skip(6);
227
- readAttributes(reader, utf8);
231
+ reader.skip(2);
232
+ const name = utf8(reader.u2());
233
+ const descriptor = utf8(reader.u2());
234
+ const constant = [];
235
+ readAttributes(reader, utf8, void 0, constant);
236
+ fieldEntries.push({
237
+ name,
238
+ descriptor,
239
+ constant: constant[0]
240
+ });
228
241
  }
229
242
  const methods = [];
230
243
  const methodCount = reader.u2();
@@ -297,6 +310,13 @@ function parseClassFile(bytes) {
297
310
  superClass,
298
311
  constants,
299
312
  methods,
313
+ fields: fieldEntries.map((field) => {
314
+ return {
315
+ name: field.name,
316
+ descriptor: field.descriptor,
317
+ constant: field.constant === void 0 ? null : literal(field.constant)
318
+ };
319
+ }),
300
320
  utf8,
301
321
  reference,
302
322
  literal,
@@ -39,6 +39,12 @@ interface ClassFile {
39
39
  superClass: string | null;
40
40
  constants: Array<Constant | null>;
41
41
  methods: MethodInfo[];
42
+ /** Each field, with its value where it is a compile-time constant (`static final int`). */
43
+ fields: Array<{
44
+ name: string;
45
+ descriptor: string;
46
+ constant: string | number | bigint | null;
47
+ }>;
42
48
  /** A pool entry as text, for a `utf8` or anything that resolves to one. */
43
49
  utf8: (index: number) => string;
44
50
  /** `owner.name:descriptor` for a field or method reference. */
@@ -1,7 +1,7 @@
1
1
  import { n as builtinPackPath } from "./builtin-WkWjATeh.js";
2
2
  import { n as LayeredResourceManager, t as FolderResourceManager } from "./manager-D6zXmFrO.js";
3
3
  import { a as prepareVersionResources, r as compareVersions } from "./prepare-DkJkZXuQ.js";
4
- import { t as exportBlockPack } from "./export-CbG2Rx3i.js";
4
+ import { t as exportBlockPack } from "./export-DgB0e5sB.js";
5
5
  import { n as layeredClasses, t as JarClassReader } from "./jar-classes-0wqWbTax.js";
6
6
  import { n as prepareModResources } from "./prepare-sj36BP90.js";
7
7
  import { t as downloadClientJar } from "./download-1wAfrGKx.js";
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import { a as prepareVersionResources, i as eraForVersion, n as GEOMETRY_DONOR_V
6
6
  import { t as curatedModelOverrides } from "./models-BsYA-NZg.js";
7
7
  import { n as harvestTintOverrides, t as curatedTintOverrides } from "./tints-CZeyKzMv.js";
8
8
  import { t as downloadClientJar } from "./download-1wAfrGKx.js";
9
- import { t as runBlocksCli } from "./cli-xBcMuKA3.js";
9
+ import { t as runBlocksCli } from "./cli-2mzPC8cy.js";
10
10
  import { t as run } from "./run-5yX5KRiI.js";
11
11
  import path from "node:path";
12
12
  import os from "node:os";
@@ -1,2 +1,2 @@
1
- import { a as parseClassFile, i as MethodInfo, n as Constant, r as ConstantTag, t as ClassFile } from "../classfile-CsLXlh5z.js";
1
+ import { a as parseClassFile, i as MethodInfo, n as Constant, r as ConstantTag, t as ClassFile } from "../classfile-Dzn0gW9M.js";
2
2
  export { ClassFile, Constant, ConstantTag, MethodInfo, parseClassFile };
@@ -1,2 +1,2 @@
1
- import { t as parseClassFile } from "../classfile-CiIDF3vc.js";
1
+ import { t as parseClassFile } from "../classfile-BJSs3JH0.js";
2
2
  export { parseClassFile };
@@ -1,6 +1,6 @@
1
- import { t as ClassFile } from "../classfile-CsLXlh5z.js";
1
+ import { t as ClassFile } from "../classfile-Dzn0gW9M.js";
2
2
  import { r as ExtractedModel } from "../model-PnQ4gV0-.js";
3
- import { t as ModelCode } from "../model-code-Csc3bs3h.js";
3
+ import { t as ModelCode } from "../model-code-BclYt1do.js";
4
4
  //#region src/entities/inherit.d.ts
5
5
  interface Ancestry {
6
6
  /** The class and its ancestors by internal name, parsed. */
@@ -1,2 +1,2 @@
1
- import { n as extractInheritedModel, t as ancestryOf } from "../inherit-BUn0Cve9.js";
1
+ import { n as extractInheritedModel, t as ancestryOf } from "../inherit-DJ45bOB_.js";
2
2
  export { ancestryOf, extractInheritedModel };
@@ -1,4 +1,4 @@
1
- import { t as ClassFile } from "../classfile-CsLXlh5z.js";
1
+ import { t as ClassFile } from "../classfile-Dzn0gW9M.js";
2
2
  import { t as Mappings } from "../mappings-DhOPQTgV.js";
3
3
  //#region src/entities/link.d.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import { a as linkEntityModel, i as classReader, n as RENDERER_ALIASES, o as normaliseModelName, r as buildModelNameIndex, t as NO_MODEL } from "../link-Cuhyrz07.js";
1
+ import { a as linkEntityModel, i as classReader, n as RENDERER_ALIASES, o as normaliseModelName, r as buildModelNameIndex, t as NO_MODEL } from "../link-IDjVJ2Ij.js";
2
2
  export { NO_MODEL, RENDERER_ALIASES, buildModelNameIndex, classReader, linkEntityModel, normaliseModelName };
@@ -1,4 +1,4 @@
1
- import { t as ClassFile } from "../classfile-CsLXlh5z.js";
1
+ import { t as ClassFile } from "../classfile-Dzn0gW9M.js";
2
2
  import { r as ExtractedModel } from "../model-PnQ4gV0-.js";
3
3
  //#region src/entities/model-bytecode.d.ts
4
4
  /** Argument slot count and shape of a descriptor's parameter list. */
@@ -1,2 +1,2 @@
1
- import { n as extractModel, r as parseDescriptor, t as extractArmourMesh } from "../model-bytecode-VaLUQfGO.js";
1
+ import { n as extractModel, r as parseDescriptor, t as extractArmourMesh } from "../model-bytecode-CXYAZ5dX.js";
2
2
  export { extractArmourMesh, extractModel, parseDescriptor };
@@ -1,2 +1,2 @@
1
- import { n as isModelCode, r as loadModelCode, t as ModelCode } from "../model-code-Csc3bs3h.js";
1
+ import { n as isModelCode, r as loadModelCode, t as ModelCode } from "../model-code-BclYt1do.js";
2
2
  export { ModelCode, isModelCode, loadModelCode };
@@ -1,2 +1,2 @@
1
- import { n as loadModelCode, t as isModelCode } from "../model-code-DbN2uVhp.js";
1
+ import { n as loadModelCode, t as isModelCode } from "../model-code-BmA5ilgt.js";
2
2
  export { isModelCode, loadModelCode };
@@ -1,11 +1,12 @@
1
1
  import { n as ResourceLocator } from "./locator-COMEtEn9.js";
2
2
  import { t as findGeoForEntity } from "./entity-geo-DbTtMlPL.js";
3
3
  import { t as EQUIPMENT_SLOTS } from "./pack-format-BP5dJMYY.js";
4
- import { n as extractModel, t as extractArmourMesh } from "./model-bytecode-VaLUQfGO.js";
5
- import { n as extractInheritedModel, t as ancestryOf } from "./inherit-BUn0Cve9.js";
6
- import { a as linkEntityModel, i as classReader, r as buildModelNameIndex } from "./link-Cuhyrz07.js";
4
+ import { t as parseClassFile } from "./classfile-BJSs3JH0.js";
5
+ import { n as extractModel, t as extractArmourMesh } from "./model-bytecode-CXYAZ5dX.js";
6
+ import { n as extractInheritedModel, t as ancestryOf } from "./inherit-DJ45bOB_.js";
7
+ import { a as linkEntityModel, i as classReader, r as buildModelNameIndex } from "./link-IDjVJ2Ij.js";
7
8
  import { c as resolveMappings, t as MappingsUnavailableError } from "./mappings-DEl_7xxQ.js";
8
- import { n as loadModelCode } from "./model-code-DbN2uVhp.js";
9
+ import { n as loadModelCode } from "./model-code-BmA5ilgt.js";
9
10
  //#region src/blocks/entity-models.ts
10
11
  /**
11
12
  * Entity geometry for the pack: link each entity to the class that builds it, read that class's
@@ -345,6 +346,22 @@ async function armourGeometry(names, mappings, read, code) {
345
346
  * the assets cannot answer, since nothing in them maps `iron_helmet` to `iron`: they follow the
346
347
  * game's own naming, and each is confirmed against a real item model before being claimed.
347
348
  */
349
+ /**
350
+ * Where the game keeps the colour an undyed leather piece takes, newest first: 1.20.5 moved it from
351
+ * the item class to the dyed-colour component. A `static final int`, so it is read off the field
352
+ * itself, since javac copies the value into every place that uses it.
353
+ */
354
+ const LEATHER_COLOUR_FIELDS = [["net.minecraft.world.item.component.DyedItemColor", "LEATHER_COLOR"], ["net.minecraft.world.item.DyeableLeatherItem", "DEFAULT_LEATHER_COLOR"]];
355
+ async function undyedLeather(mappings, read) {
356
+ for (const [owner, field] of LEATHER_COLOUR_FIELDS) {
357
+ const bytes = await read((mappings.obfuscatedOf.get(owner) ?? owner).replaceAll(".", "/"));
358
+ if (!bytes) continue;
359
+ const name = mappings.fieldOf.get(`${owner}.${field}`) ?? field;
360
+ const value = parseClassFile(bytes).fields.find((candidate) => candidate.name === name)?.constant;
361
+ if (typeof value === "number") return `#${(value & 16777215).toString(16).padStart(6, "0")}`;
362
+ }
363
+ return null;
364
+ }
348
365
  async function collectEquipment(names, mappings, read, code, resources, models, spriteIds) {
349
366
  if (!resources) return null;
350
367
  const found = await armourGeometry(names, mappings, read, code);
@@ -385,6 +402,7 @@ async function collectEquipment(names, mappings, read, code, resources, models,
385
402
  }
386
403
  }
387
404
  const trims = await collectArmourTrims(resources, spriteIds);
405
+ const leather = dyeable.includes("minecraft:leather") ? await undyedLeather(mappings, read) : null;
388
406
  const modelKey = `${found.className}#armor`;
389
407
  models[modelKey] = {
390
408
  textureSize: [...found.model.textureSize],
@@ -399,6 +417,7 @@ async function collectEquipment(names, mappings, read, code, resources, models,
399
417
  materials,
400
418
  items,
401
419
  dyeable,
420
+ ...leather && { undyed: { "minecraft:leather": leather } },
402
421
  trims
403
422
  };
404
423
  }
@@ -1,4 +1,4 @@
1
- import { t as parseClassFile } from "./classfile-CiIDF3vc.js";
1
+ import { t as parseClassFile } from "./classfile-BJSs3JH0.js";
2
2
  import { c as resolveMappings, t as MappingsUnavailableError } from "./mappings-DEl_7xxQ.js";
3
3
  //#region src/blocks/entity-sizes.ts
4
4
  /**
@@ -83,6 +83,8 @@ interface BlockPackResult {
83
83
  states: number;
84
84
  /** Rules in `game-rules.json`; `0` means the file was not written. */
85
85
  gameRules: number;
86
+ /** Block and item names in `names.json`; `0` means the file was not written. */
87
+ names: number;
86
88
  /** Files actually written — the only trustworthy success signal. */
87
89
  writtenFiles: number;
88
90
  failures: BlockPackFailure[];
@@ -7,13 +7,14 @@ import { t as collectDatapack } from "./datapack-D6eH46ay.js";
7
7
  import { a as salvageJson, i as resolveTexture, t as ModelLoader } from "./loader-qOH0Jynq.js";
8
8
  import { t as enderStorageBlockModel } from "./ender-storage-Dgomp6r2.js";
9
9
  import { t as collectEntities } from "./entities-rQ4TZjEo.js";
10
- import { n as collectEntityGeometry } from "./entity-models-BYAxrTsk.js";
11
- import { t as collectEntitySizes } from "./entity-sizes-CpO1gA7p.js";
12
- import { t as collectGameRules } from "./game-rules-DuLlFc7o.js";
10
+ import { n as collectEntityGeometry } from "./entity-models-vFl_EwfA.js";
11
+ import { t as collectEntitySizes } from "./entity-sizes-DspxgSUA.js";
12
+ import { t as collectGameRules } from "./game-rules-BDPTopVW.js";
13
13
  import { t as geoBlockModel } from "./geo-blocks-W79q5A0f.js";
14
14
  import { n as discoverItems } from "./discovery-CD0QqxSF.js";
15
15
  import { t as collectItemSprites } from "./item-sprites-CwiEBEAJ.js";
16
- import { n as collectBlockLight } from "./light-CC3VMsjl.js";
16
+ import { n as collectBlockLight } from "./light-BnaYFouC.js";
17
+ import { t as collectNames } from "./names-GLa5TyL7.js";
17
18
  import { n as buildObjMesh } from "./obj-mesh-BFhtTBXX.js";
18
19
  import { n as buildSpriteSheet, t as MISSING_SPRITE } from "./sprite-sheet-LQAEtGkp.js";
19
20
  import { t as readBlockStates } from "./states-BvoZA-ql.js";
@@ -698,6 +699,7 @@ async function exportBlockPack(options) {
698
699
  });
699
700
  }
700
701
  }
702
+ const states = options.reports === void 0 ? null : await readBlockStates(options.reports);
701
703
  let lightPack = {};
702
704
  let behaviourPack = {};
703
705
  if (options.classes) {
@@ -706,6 +708,7 @@ async function exportBlockPack(options) {
706
708
  cacheDir: options.cacheDir ?? output,
707
709
  classes: options.classes,
708
710
  blockIds: [.../* @__PURE__ */ new Set([...blockLocators.map((locator) => locator.toString()), ...Object.keys(blockStates)])],
711
+ defaultStateOf: (id) => states?.[id]?.default ?? null,
709
712
  onProgress: (count, total) => report("light", count, total)
710
713
  });
711
714
  lightPack = sortedByKey(collected.light);
@@ -730,8 +733,9 @@ async function exportBlockPack(options) {
730
733
  reason: "datapack file is unreadable or not in the shape its folder implies; left out"
731
734
  });
732
735
  const tagCount = Object.values(datapack.tags).reduce((sum, registry) => sum + Object.keys(registry).length, 0);
736
+ const names = await collectNames(resources, namespaces);
737
+ const nameCount = Object.keys(names.block).length + Object.keys(names.item).length;
733
738
  const gameRules = options.classes && namespaces.includes("minecraft") ? await collectGameRules(options.classes) : {};
734
- const states = options.reports === void 0 ? null : await readBlockStates(options.reports);
735
739
  const statesPack = states === null ? null : Object.fromEntries(Object.entries(states).filter(([id]) => namespaces.includes(id.split(":", 1)[0])));
736
740
  let itemPack = null;
737
741
  let itemPages = [];
@@ -946,6 +950,10 @@ async function exportBlockPack(options) {
946
950
  const tags = Object.fromEntries(Object.entries(datapack.tags).map(([registry, entries]) => [registry, sortedByKey(entries)]));
947
951
  await emit("tags.json", JSON.stringify(sortedByKey(tags)));
948
952
  }
953
+ if (nameCount > 0) await emit("names.json", JSON.stringify({
954
+ block: sortedByKey(names.block),
955
+ item: sortedByKey(names.item)
956
+ }));
949
957
  if (Object.keys(gameRules).length > 0) await emit("game-rules.json", JSON.stringify(sortedByKey(gameRules)));
950
958
  if (statesPack !== null && Object.keys(statesPack).length > 0) await emit("states.json", JSON.stringify(sortedByKey(statesPack)));
951
959
  if (Object.keys(datapack.advancements).length > 0) await emit("advancements.json", JSON.stringify(sortedByKey(datapack.advancements)));
@@ -971,6 +979,7 @@ async function exportBlockPack(options) {
971
979
  advancements: Object.keys(datapack.advancements).length,
972
980
  states: Object.keys(statesPack ?? {}).length,
973
981
  gameRules: Object.keys(gameRules).length,
982
+ names: nameCount,
974
983
  failures: failures.length
975
984
  };
976
985
  await emit("meta.json", JSON.stringify({
@@ -1,5 +1,5 @@
1
- import { t as parseClassFile } from "./classfile-CiIDF3vc.js";
2
- import { n as instructions } from "./entity-sizes-CpO1gA7p.js";
1
+ import { t as parseClassFile } from "./classfile-BJSs3JH0.js";
2
+ import { n as instructions } from "./entity-sizes-DspxgSUA.js";
3
3
  //#region src/blocks/game-rules.ts
4
4
  /**
5
5
  * The version's game rules: each one's name, whether it is on/off or a number, and its default.
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ import { a as BlockStateMultipartCase, d as matchesCondition, f as parseBlockSta
8
8
  import { a as resolveTexture, n as ModelResolutionError, o as salvageJson, r as ResolvedModel, t as ModelLoader } from "./loader-BYyPIs9f.js";
9
9
  import { i as buildObjMesh, n as ObjMesh, r as ObjMeshError, t as MeshGroup } from "./obj-mesh-CzL0lOlJ.js";
10
10
  import { a as buildBlockTints, i as UNREGISTERED_TINTS, n as BlockTintPack, t as BlockTint } from "./tints-DwFmEkf3.js";
11
- import { i as exportBlockPack, n as BlockPackResult, r as ExportBlockPackOptions, t as BlockPackFailure } from "./export-HEoqcV-Y.js";
11
+ import { i as exportBlockPack, n as BlockPackResult, r as ExportBlockPackOptions, t as BlockPackFailure } from "./export-CqeTinYL.js";
12
12
  import { s as builtinDynamicResources } from "./generators-hu_vk10m.js";
13
13
  import { d as toFloatTexture, n as FloatTexture, u as toByteTexture } from "./blend-mJAeQB3C.js";
14
14
  import { a as LightingProfileName, i as LightingProfile, r as LightSource, u as lightsForProfile } from "./lighting-3FGRC3Af.js";
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import { t as packAtlas } from "./atlas-pack-CoOih7By.js";
16
16
  import { n as buildBlockTints, t as UNREGISTERED_TINTS } from "./tints-Cl0r-Ol3.js";
17
17
  import { o as createAtlasResolver, s as parseAtlasSources, t as AtlasSourceError } from "./sources-DYY5Qu-t.js";
18
18
  import { n as TextureLoader, r as TextureResolutionError, t as AnimatedTexture } from "./loader-CsgtBuBo.js";
19
- import { t as exportBlockPack } from "./export-CbG2Rx3i.js";
19
+ import { t as exportBlockPack } from "./export-DgB0e5sB.js";
20
20
  import { n as prepareModResources } from "./prepare-sj36BP90.js";
21
21
  import { n as encodeIcon, t as encodeAnimatedIcon } from "./encode-LR9wxigC.js";
22
22
  import { a as builtinDynamicResources } from "./generators-D6giKoab.js";
@@ -1,6 +1,6 @@
1
- import { t as parseClassFile } from "./classfile-CiIDF3vc.js";
1
+ import { t as parseClassFile } from "./classfile-BJSs3JH0.js";
2
2
  import { a as mergeModels, i as dedupeCubes } from "./merge-DeHruviG.js";
3
- import { n as extractModel } from "./model-bytecode-VaLUQfGO.js";
3
+ import { n as extractModel } from "./model-bytecode-CXYAZ5dX.js";
4
4
  //#region src/entities/inherit.ts
5
5
  /**
6
6
  * A model class read together with its ancestors.
@@ -1,8 +1,9 @@
1
1
  import { r as compareVersions } from "./prepare-DkJkZXuQ.js";
2
- import { t as parseClassFile } from "./classfile-CiIDF3vc.js";
2
+ import { t as parseClassFile } from "./classfile-BJSs3JH0.js";
3
3
  import { c as resolveMappings, s as remapDescriptor, t as MappingsUnavailableError } from "./mappings-DEl_7xxQ.js";
4
- import { t as blockBehaviour } from "./block-behaviour-D-SG2Xfp.js";
5
- import { t as extractBlockLight } from "./light-bytecode-DYxb6pJk.js";
4
+ import { t as blockBehaviour } from "./block-behaviour-DVjqeSkv.js";
5
+ import { i as overrideOf, n as constantFluidOf, t as alwaysInvisible } from "./block-overrides-XtxICunI.js";
6
+ import { t as extractBlockLight } from "./light-bytecode-hhkkjMVi.js";
6
7
  //#region src/blocks/light.ts
7
8
  /**
8
9
  * Block light emission for the exported pack: `light.json`.
@@ -301,6 +302,7 @@ async function collectBlockLight(options) {
301
302
  remap,
302
303
  remapClass,
303
304
  nameOf,
305
+ defaultStateOf: options.defaultStateOf,
304
306
  propsClasses,
305
307
  lightGetters: findLightGetters(roots, propsClasses, resolve, notes),
306
308
  isVanillaClass: (name) => mappings.originalOf.size === 0 || mappings.originalOf.has(name.replaceAll("/", ".")) || name.startsWith("net/minecraft/") || name.startsWith("com/mojang/")
@@ -336,7 +338,16 @@ async function collectBlockLight(options) {
336
338
  const behaviourFailures = [];
337
339
  if (mappings.originalOf.size > 0 || isClearJar) for (const id of blockIds) {
338
340
  const registration = NOT_BLOCKS.has(id) ? null : extraction.registrationOf(id);
339
- const read = registration ? blockBehaviour(registration, extraction) : null;
341
+ const blockType = registration?.blockType ?? registration?.block?.type ?? null;
342
+ const overrides = {
343
+ resolve,
344
+ nameOf
345
+ };
346
+ const read = registration ? blockBehaviour(registration, extraction, {
347
+ of: (names) => blockType ? overrideOf(overrides, blockType, names) : null,
348
+ fluid: (method) => constantFluidOf(overrides, method),
349
+ invisible: (method) => alwaysInvisible(overrides, method)
350
+ }) : null;
340
351
  if (read) {
341
352
  behaviour[id] = read.behaviour;
342
353
  for (const reason of read.failures) behaviourFailures.push({
@@ -1,5 +1,6 @@
1
- import { r as parseDescriptor } from "./model-bytecode-VaLUQfGO.js";
2
- import { n as statedMapColor } from "./block-behaviour-D-SG2Xfp.js";
1
+ import { r as parseDescriptor } from "./model-bytecode-CXYAZ5dX.js";
2
+ import { n as instructions } from "./entity-sizes-DspxgSUA.js";
3
+ import { n as statedMapColor } from "./block-behaviour-DVjqeSkv.js";
3
4
  //#region src/blocks/light-bytecode.ts
4
5
  /**
5
6
  * Block light emission, read out of the code that registers blocks.
@@ -426,6 +427,63 @@ var Interpreter = class Interpreter {
426
427
  const parent = this.shared.source.resolve(handle.type)?.superClass ?? null;
427
428
  return parent === "java/lang/Enum" || parent !== null && this.shared.source.resolve(parent)?.superClass === "java/lang/Enum";
428
429
  }
430
+ /**
431
+ * A function of state run at a registered block's default state, which only the data generator's
432
+ * report states: a sign takes its log's colour, and a log is `axis=y` until placed otherwise.
433
+ */
434
+ atDefaultState(block, fn) {
435
+ const { source, registrations } = this.shared;
436
+ let values = null;
437
+ for (const [name, registration] of registrations) {
438
+ if (registration.block !== block || values) continue;
439
+ const id = name.includes(":") ? name : registration.vanilla ? `minecraft:${name}` : null;
440
+ values = id ? source.defaultStateOf?.(id) ?? null : null;
441
+ }
442
+ if (!values) return null;
443
+ const saved = {
444
+ steps: this.shared.steps,
445
+ frames: this.shared.frames,
446
+ probe: this.shared.probe
447
+ };
448
+ const probe = {
449
+ values: new Map(Object.entries(values)),
450
+ domains: /* @__PURE__ */ new Map(),
451
+ reads: /* @__PURE__ */ new Set(),
452
+ failure: null
453
+ };
454
+ this.shared.probe = probe;
455
+ this.shared.steps = Math.min(saved.steps, CTOR_BUDGET);
456
+ try {
457
+ const result = this.invokeLambda(fn, [{
458
+ kind: "state",
459
+ probe
460
+ }]);
461
+ return probe.failure ? null : result;
462
+ } finally {
463
+ this.shared.steps = saved.steps - Math.max(0, Math.min(saved.steps, CTOR_BUDGET) - this.shared.steps);
464
+ this.shared.frames = saved.frames;
465
+ this.shared.probe = saved.probe;
466
+ }
467
+ }
468
+ /**
469
+ * The class a factory lambda constructs, read off its body rather than run: `props -> new
470
+ * StairBlock(base, props)` builds a `StairBlock`. What a stair overrides lives on that class.
471
+ */
472
+ constructedIn(lambda) {
473
+ const reference = this.shared.source.remap({
474
+ owner: lambda.owner,
475
+ name: lambda.name,
476
+ descriptor: lambda.descriptor
477
+ }, false);
478
+ const target = findMethod(this.shared.source, reference.owner, reference.name, reference.descriptor);
479
+ if (!target) return null;
480
+ for (const { op, index } of instructions(target.code)) {
481
+ if (op !== 187) continue;
482
+ const name = target.classFile.utf8(index);
483
+ if (!name.startsWith("java/") && !this.isPropsType(name)) return this.shared.source.remapClass(name);
484
+ }
485
+ return null;
486
+ }
429
487
  detectRegistration(args, site) {
430
488
  const names = [];
431
489
  for (const arg of args) if (arg.kind === "string") names.push(arg.value);
@@ -435,16 +493,17 @@ var Interpreter = class Interpreter {
435
493
  }
436
494
  const ids = names.filter((name) => looksLikeId(name));
437
495
  if (ids.length === 0) return null;
438
- const known = ids.map((name) => this.shared.registrations.get(name)).find((entry) => entry !== void 0);
496
+ const known = ids.map((name) => this.shared.registrations.get(name)).findLast((entry) => entry !== void 0);
439
497
  if (known && ids.every((name) => this.shared.registrations.has(name))) return known.block ?? this.blockFor(known);
440
498
  let props = null;
441
499
  let block = null;
442
500
  let blockType = null;
443
501
  for (const arg of args) if (arg.kind === "object" && arg.handle.isProps) props ??= arg.handle;
444
- else if (arg.kind === "object" && arg.handle.props) block ??= arg.handle;
502
+ else if (arg.kind === "object" && arg.handle.props && !this.shared.registeredBlocks.has(arg.handle)) block ??= arg.handle;
445
503
  else if (arg.kind === "lambda" && arg.name === "<init>") blockType ??= this.shared.source.remapClass(arg.owner);
504
+ else if (arg.kind === "lambda") blockType ??= this.constructedIn(arg);
446
505
  if (!props && !block) for (const arg of args) {
447
- if (arg.kind !== "lambda") continue;
506
+ if (arg.kind !== "lambda" || parseDescriptor(arg.descriptor).args.length > arg.captured.length) continue;
448
507
  const made = this.invokeLambda(arg, []);
449
508
  if (made?.kind === "object" && made.handle.props) {
450
509
  block = made.handle;
@@ -460,7 +519,9 @@ var Interpreter = class Interpreter {
460
519
  vanilla: this.caller !== null && this.shared.source.isVanillaClass(this.caller)
461
520
  };
462
521
  for (const name of ids) if (!this.shared.registrations.has(name)) this.shared.registrations.set(name, registration);
463
- return block ?? this.blockFor(registration);
522
+ const registered = block ?? this.blockFor(registration);
523
+ this.shared.registeredBlocks.add(registered);
524
+ return registered;
464
525
  }
465
526
  /**
466
527
  * The block a registration stands for, when the call was handed properties and a factory rather than
@@ -840,7 +901,7 @@ var Interpreter = class Interpreter {
840
901
  return;
841
902
  }
842
903
  }
843
- const registered = this.detectRegistration(args, `${remapped.owner}.${remapped.name}${remapped.descriptor}`);
904
+ const registered = returns.startsWith("L") && source.resolve(returns.slice(1, -1))?.superClass === "java/lang/Record" ? null : this.detectRegistration(args, `${remapped.owner}.${remapped.name}${remapped.descriptor}`);
844
905
  if (registered) {
845
906
  this.push(returns === "V" ? null : returns.startsWith("L") ? {
846
907
  kind: "object",
@@ -853,8 +914,9 @@ var Interpreter = class Interpreter {
853
914
  const named = source.nameOf?.(reference, false) ?? remapped.name;
854
915
  if (target.props && args.length === 0 && (named === "defaultMapColor" || named === "defaultMaterialColor")) {
855
916
  const colour = statedMapColor(target.props);
856
- if (colour && colour.kind !== "lambda") {
857
- this.push(colour);
917
+ const answer = colour?.kind === "lambda" ? this.atDefaultState(target, colour) : colour;
918
+ if (answer) {
919
+ this.push(answer);
858
920
  return;
859
921
  }
860
922
  }
@@ -1580,6 +1642,27 @@ var Interpreter = class Interpreter {
1580
1642
  this.shared.probe = null;
1581
1643
  }
1582
1644
  }
1645
+ /**
1646
+ * Runs a block class's own method of a state (`getLightValue(state)`, `useShapeForLightOcclusion(state)`)
1647
+ * on the block, the state first and anything after it unknown; null where the interpreter lost it.
1648
+ */
1649
+ evaluateMethod(owner, name, descriptor, receiver, probe, typedArguments = false) {
1650
+ const method = findMethod(this.shared.source, owner, name, descriptor);
1651
+ if (!method) return null;
1652
+ const self = {
1653
+ kind: "object",
1654
+ handle: receiver ?? this.handle(owner)
1655
+ };
1656
+ const rest = parseDescriptor(descriptor).args.slice(1).map((shape) => typedArguments && shape.startsWith("L") ? {
1657
+ kind: "object",
1658
+ handle: this.handle(shape.slice(1, -1))
1659
+ } : UNKNOWN);
1660
+ const inlined = this.inline(method.classFile.thisClass, name, descriptor, self, [{
1661
+ kind: "state",
1662
+ probe
1663
+ }, ...rest]);
1664
+ return inlined.ok ? inlined.value : null;
1665
+ }
1583
1666
  /** Evaluates a light spec against one state; null where the interpreter lost the value. */
1584
1667
  evaluate(spec, probe) {
1585
1668
  this.shared.probe = probe;
@@ -1592,20 +1675,8 @@ var Interpreter = class Interpreter {
1592
1675
  };
1593
1676
  let result;
1594
1677
  if (spec.kind === "function") result = this.invokeLambda(spec.fn, [state]);
1595
- else if (spec.kind === "method") {
1596
- const method = findMethod(this.shared.source, spec.owner, spec.getter.name, spec.getter.descriptor);
1597
- if (!method) return null;
1598
- const receiver = spec.receiver ? {
1599
- kind: "object",
1600
- handle: spec.receiver
1601
- } : {
1602
- kind: "object",
1603
- handle: this.handle(spec.owner)
1604
- };
1605
- const extra = parseDescriptor(spec.getter.descriptor).args.length - 1;
1606
- const inlined = this.inline(method.classFile.thisClass, spec.getter.name, spec.getter.descriptor, receiver, [state, ...Array.from({ length: extra }, () => UNKNOWN)]);
1607
- result = inlined.ok ? inlined.value : null;
1608
- } else return spec.kind === "constant" ? spec.level : null;
1678
+ else if (spec.kind === "method") result = this.evaluateMethod(spec.owner, spec.getter.name, spec.getter.descriptor, spec.receiver, probe);
1679
+ else return spec.kind === "constant" ? spec.level : null;
1609
1680
  if (probe.failure || result?.kind !== "number" || !Number.isFinite(result.value)) return null;
1610
1681
  return Math.max(0, Math.min(15, Math.round(result.value)));
1611
1682
  } finally {
@@ -1679,6 +1750,7 @@ function extractBlockLight(roots, source) {
1679
1750
  statics: /* @__PURE__ */ new Map(),
1680
1751
  initialised: /* @__PURE__ */ new Set(),
1681
1752
  registrations: /* @__PURE__ */ new Map(),
1753
+ registeredBlocks: /* @__PURE__ */ new Set(),
1682
1754
  steps: STEP_BUDGET,
1683
1755
  frames: FRAME_BUDGET,
1684
1756
  notes: [],
@@ -1744,6 +1816,20 @@ function extractBlockLight(roots, source) {
1744
1816
  return value === null ? null : read(value);
1745
1817
  }, "state function");
1746
1818
  };
1819
+ const tabulateMethod = (registration, method, read) => {
1820
+ const evaluator = new Interpreter(shared);
1821
+ return tabulateStates(shared, (probe) => {
1822
+ shared.probe = probe;
1823
+ shared.steps = STEP_BUDGET;
1824
+ shared.frames = FRAME_BUDGET;
1825
+ try {
1826
+ const value = evaluator.evaluateMethod(method.owner, method.name, method.descriptor, registration.block, probe, true);
1827
+ return value === null || probe.failure ? null : read(value);
1828
+ } finally {
1829
+ shared.probe = null;
1830
+ }
1831
+ }, `${method.name} override`);
1832
+ };
1747
1833
  const describe = (blockId) => {
1748
1834
  const registration = registrationOf(blockId);
1749
1835
  if (!registration) return `${blockId}: not registered`;
@@ -1756,6 +1842,7 @@ function extractBlockLight(roots, source) {
1756
1842
  lightOf,
1757
1843
  registrationOf,
1758
1844
  tabulate,
1845
+ tabulateMethod,
1759
1846
  describe
1760
1847
  };
1761
1848
  }
@@ -1,5 +1,5 @@
1
1
  import { n as BlockProperties } from "./blockstate-eval-BzznRcVY.js";
2
- import { j as BlockPackLight } from "./block-behaviour-9Tj_GIUC.js";
2
+ import { j as BlockPackLight } from "./block-behaviour-CzK3KVLx.js";
3
3
  //#region src/blocks/light-eval.d.ts
4
4
  /**
5
5
  * The light a block emits in the given state, 0–15.
@@ -1,4 +1,4 @@
1
- import { t as parseClassFile } from "./classfile-CiIDF3vc.js";
1
+ import { t as parseClassFile } from "./classfile-BJSs3JH0.js";
2
2
  //#region src/entities/link.ts
3
3
  /**
4
4
  * Which class holds a given entity's geometry.
@@ -1,4 +1,4 @@
1
- import { t as parseClassFile } from "./classfile-CiIDF3vc.js";
1
+ import { t as parseClassFile } from "./classfile-BJSs3JH0.js";
2
2
  import { a as mergeModels, r as cubesOf, t as buildsOwnMesh } from "./merge-DeHruviG.js";
3
3
  //#region src/entities/model-bytecode.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as ClassFile } from "./classfile-CsLXlh5z.js";
1
+ import { t as ClassFile } from "./classfile-Dzn0gW9M.js";
2
2
  //#region src/entities/model-code.d.ts
3
3
  interface ModelCode {
4
4
  /** The parsed class, when it is model code a call may be followed into. */
@@ -1,4 +1,4 @@
1
- import { t as parseClassFile } from "./classfile-CiIDF3vc.js";
1
+ import { t as parseClassFile } from "./classfile-BJSs3JH0.js";
2
2
  //#region src/entities/model-code.ts
3
3
  /**
4
4
  * Which classes in a jar count as model code, and their parsed form.
@@ -0,0 +1,10 @@
1
+ import { a as ResourceManager } from "./manager-Ct0dEOMg.js";
2
+ //#region src/blocks/names.d.ts
3
+ /** `names.json`: display names by id, one table per registry. */
4
+ interface NamePack {
5
+ block: Record<string, string>;
6
+ item: Record<string, string>;
7
+ }
8
+ declare function collectNames(resources: ResourceManager, namespaces: readonly string[]): Promise<NamePack>;
9
+ //#endregion
10
+ export { collectNames as n, NamePack as t };
@@ -0,0 +1,36 @@
1
+ import { n as ResourceLocator } from "./locator-COMEtEn9.js";
2
+ //#region src/blocks/names.ts
3
+ /**
4
+ * Block and item display names, from each namespace's own `en_us` lang file.
5
+ *
6
+ * `block.minecraft.tnt` is "TNT" and `block.minecraft.short_grass` is "Short Grass" (before 1.20.3,
7
+ * "Grass"): the version's own English, which a consumer would otherwise guess by title-casing an id.
8
+ * Keys with more segments than `<kind>.<ns>.<name>` are a description or a variant's label, never an
9
+ * id, and are left out.
10
+ */
11
+ const NAME_KEY_SEGMENTS = 3;
12
+ async function collectNames(resources, namespaces) {
13
+ const names = {
14
+ block: {},
15
+ item: {}
16
+ };
17
+ for (const namespace of namespaces) {
18
+ const raw = await resources.getResource("lang", new ResourceLocator(namespace, "en_us"));
19
+ if (!raw) continue;
20
+ let lang;
21
+ try {
22
+ lang = JSON.parse(raw.toString("utf8"));
23
+ } catch {
24
+ continue;
25
+ }
26
+ for (const [key, value] of Object.entries(lang)) {
27
+ const parts = key.split(".");
28
+ const [kind, keyNamespace, name] = parts;
29
+ if (parts.length !== NAME_KEY_SEGMENTS || keyNamespace !== namespace || typeof value !== "string") continue;
30
+ if (kind === "block" || kind === "item") names[kind][`${namespace}:${name}`] = value;
31
+ }
32
+ }
33
+ return names;
34
+ }
35
+ //#endregion
36
+ export { collectNames as t };
package/dist/pack.d.ts CHANGED
@@ -3,6 +3,6 @@ import { a as BlockStateMultipartCase, d as matchesCondition, n as BlockProperti
3
3
  import { t as GameRule } from "./game-rules-ThvdDG3B.js";
4
4
  import { n as ObjMesh, t as MeshGroup } from "./obj-mesh-CzL0lOlJ.js";
5
5
  import { n as BlockTintPack, t as BlockTint } from "./tints-DwFmEkf3.js";
6
- import { B as BlockPackTagsFile, C as BlockPackBlockState, F as BlockPackModelsFile, H as BlockPackVariant, I as BlockPackRenderLayer, L as BlockPackSprite, M as BlockPackLightFile, N as BlockPackMetaFile, O as BlockPackFace, P as BlockPackModel, R as BlockPackSpriteFrame, S as BlockPackBiomesFile, T as BlockPackElement, V as BlockPackTintsFile, b as BlockPackAtlasPage, j as BlockPackLight, k as BlockPackGameRulesFile, n as PushReactionName, t as BlockBehaviour, v as BlockPackAdvancementsFile, w as BlockPackBlockStatesFile, x as BlockPackBehaviourFile, y as BlockPackAtlasFile, z as BlockPackStatesFile } from "./block-behaviour-9Tj_GIUC.js";
7
- import { t as blockLightLevel } from "./light-eval-DMjK6xnb.js";
8
- export { type BiomeClimate, type BiomeClimatePack, type BlockBehaviour, type BlockModelVariant, type BlockPackAdvancementsFile, type BlockPackAtlasFile, type BlockPackAtlasPage, type BlockPackBehaviourFile, type BlockPackBiomesFile, type BlockPackBlockState, type BlockPackBlockStatesFile, type BlockPackElement, type BlockPackFace, type BlockPackGameRulesFile, type BlockPackLight, type BlockPackLightFile, type BlockPackMetaFile, type BlockPackModel, type BlockPackModelsFile, type BlockPackRenderLayer, type BlockPackSprite, type BlockPackSpriteFrame, type BlockPackStatesFile, type BlockPackTagsFile, type BlockPackTintsFile, type BlockPackVariant, type BlockProperties, type BlockStateDefinition, type BlockStateMultipartCase, type BlockStateVariantCase, type BlockTint, type BlockTintPack, type GameRule, type MeshGroup, type MultipartCondition, type ObjMesh, type PushReactionName, blockLightLevel, evaluateBlockState, matchesCondition, weightedVariantIndex };
6
+ import { B as BlockPackStatesFile, C as BlockPackBlockState, F as BlockPackModelsFile, H as BlockPackTintsFile, I as BlockPackNamesFile, L as BlockPackRenderLayer, M as BlockPackLightFile, N as BlockPackMetaFile, O as BlockPackFace, P as BlockPackModel, R as BlockPackSprite, S as BlockPackBiomesFile, T as BlockPackElement, U as BlockPackVariant, V as BlockPackTagsFile, b as BlockPackAtlasPage, j as BlockPackLight, k as BlockPackGameRulesFile, n as PushReactionName, t as BlockBehaviour, v as BlockPackAdvancementsFile, w as BlockPackBlockStatesFile, x as BlockPackBehaviourFile, y as BlockPackAtlasFile, z as BlockPackSpriteFrame } from "./block-behaviour-CzK3KVLx.js";
7
+ import { t as blockLightLevel } from "./light-eval-B4q-aVcf.js";
8
+ export { type BiomeClimate, type BiomeClimatePack, type BlockBehaviour, type BlockModelVariant, type BlockPackAdvancementsFile, type BlockPackAtlasFile, type BlockPackAtlasPage, type BlockPackBehaviourFile, type BlockPackBiomesFile, type BlockPackBlockState, type BlockPackBlockStatesFile, type BlockPackElement, type BlockPackFace, type BlockPackGameRulesFile, type BlockPackLight, type BlockPackLightFile, type BlockPackMetaFile, type BlockPackModel, type BlockPackModelsFile, type BlockPackNamesFile, type BlockPackRenderLayer, type BlockPackSprite, type BlockPackSpriteFrame, type BlockPackStatesFile, type BlockPackTagsFile, type BlockPackTintsFile, type BlockPackVariant, type BlockProperties, type BlockStateDefinition, type BlockStateMultipartCase, type BlockStateVariantCase, type BlockTint, type BlockTintPack, type GameRule, type MeshGroup, type MultipartCondition, type ObjMesh, type PushReactionName, blockLightLevel, evaluateBlockState, matchesCondition, weightedVariantIndex };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodecraft/rendermite",
3
- "version": "1.9.0",
3
+ "version": "1.10.1",
4
4
  "description": "Minecraft item icon renderer: renders inventory-identical item icons from vanilla and modded assets across game versions, outputting optimized PNG/WebP/AVIF plus CSS and a JSON item library.",
5
5
  "type": "module",
6
6
  "license": "MIT",