minecraft-inventory 0.1.3 → 0.1.5

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.
@@ -94,6 +94,7 @@ export const inventoryDefinitions = makeInventoryDefinitions({
94
94
  backgroundTexture: '1.21.11/textures/gui/container/inventory.png',
95
95
  backgroundWidth: 176,
96
96
  backgroundHeight: 166,
97
+ entityDisplay: { x: 26, y: 8, width: 49, height: 70 },
97
98
  slots: [
98
99
  // Result (0)
99
100
  { x: 154, y: 28, group: 'result', resultSlot: true },
@@ -124,15 +125,88 @@ export const inventoryDefinitions = makeInventoryDefinitions({
124
125
  ],
125
126
  },
126
127
 
128
+ // generic_9x1..9x6 all use generic_54.png (the 6-row chest texture, 176×222).
129
+ // InventoryBackground canvas-stitches rows < 6: takes the top N rows from the source
130
+ // (y=0..topH-1, where topH = N*18+17) then the player-inventory section starting at
131
+ // y=SRC_PLAYER_Y=125 and composites them.
132
+ // Output height formula: N*18+17 + (222-125) = N*18+17+97 = N*18+114.
133
+ // Slot formula: container at y=18, player at y = N*18+30 (13px frame into player section).
127
134
  generic_9x1: {
128
135
  name: 'generic_9x1',
129
136
  title: 'Container',
130
- backgroundTexture: '1.21.11/textures/gui/container/shulker_box.png',
137
+ backgroundTexture: '1.21.11/textures/gui/container/generic_54.png',
131
138
  backgroundWidth: 176,
132
- backgroundHeight: 96,
139
+ backgroundHeight: 132, // 1*18 + 114
140
+ containerRows: 1,
133
141
  slots: [
134
142
  ...gridSlots(9, 1, 8, 18, 'container'),
135
- ...playerInv(14),
143
+ ...playerInv(48), // 1*18 + 30
144
+ ],
145
+ },
146
+
147
+ generic_9x2: {
148
+ name: 'generic_9x2',
149
+ title: 'Container',
150
+ backgroundTexture: '1.21.11/textures/gui/container/generic_54.png',
151
+ backgroundWidth: 176,
152
+ backgroundHeight: 150, // 2*18 + 114
153
+ containerRows: 2,
154
+ slots: [
155
+ ...gridSlots(9, 2, 8, 18, 'container'),
156
+ ...playerInv(66), // 2*18 + 30
157
+ ],
158
+ },
159
+
160
+ generic_9x3: {
161
+ name: 'generic_9x3',
162
+ title: 'Container',
163
+ backgroundTexture: '1.21.11/textures/gui/container/generic_54.png',
164
+ backgroundWidth: 176,
165
+ backgroundHeight: 168, // 3*18 + 114
166
+ containerRows: 3,
167
+ playerInventoryOffset: { x: 8, y: 84 },
168
+ slots: [
169
+ ...gridSlots(9, 3, 8, 18, 'container'),
170
+ ...playerInv(84), // 3*18 + 30
171
+ ],
172
+ },
173
+
174
+ generic_9x4: {
175
+ name: 'generic_9x4',
176
+ title: 'Container',
177
+ backgroundTexture: '1.21.11/textures/gui/container/generic_54.png',
178
+ backgroundWidth: 176,
179
+ backgroundHeight: 186, // 4*18 + 114
180
+ containerRows: 4,
181
+ slots: [
182
+ ...gridSlots(9, 4, 8, 18, 'container'),
183
+ ...playerInv(102), // 4*18 + 30
184
+ ],
185
+ },
186
+
187
+ generic_9x5: {
188
+ name: 'generic_9x5',
189
+ title: 'Container',
190
+ backgroundTexture: '1.21.11/textures/gui/container/generic_54.png',
191
+ backgroundWidth: 176,
192
+ backgroundHeight: 204, // 5*18 + 114
193
+ containerRows: 5,
194
+ slots: [
195
+ ...gridSlots(9, 5, 8, 18, 'container'),
196
+ ...playerInv(120), // 5*18 + 30
197
+ ],
198
+ },
199
+
200
+ generic_9x6: {
201
+ name: 'generic_9x6',
202
+ title: 'Container',
203
+ backgroundTexture: '1.21.11/textures/gui/container/generic_54.png',
204
+ backgroundWidth: 176,
205
+ backgroundHeight: 222, // full 6-row texture, no stitching needed (N*18+114 = 222)
206
+ playerInventoryOffset: { x: 8, y: 140 },
207
+ slots: [
208
+ ...gridSlots(9, 6, 8, 18, 'container'),
209
+ ...playerInv(140), // matches large_chest
136
210
  ],
137
211
  },
138
212
 
@@ -321,6 +395,7 @@ export const inventoryDefinitions = makeInventoryDefinitions({
321
395
  backgroundTexture: '1.21.11/textures/gui/container/anvil.png',
322
396
  backgroundWidth: 176,
323
397
  backgroundHeight: 166,
398
+ titleOffset: { x: 52, y: 0 },
324
399
  properties: {
325
400
  repairCost: { dataSlot: 0, description: 'Level cost' },
326
401
  },
@@ -444,7 +519,7 @@ export const inventoryDefinitions = makeInventoryDefinitions({
444
519
 
445
520
  beacon: {
446
521
  name: 'beacon',
447
- title: 'Beacon',
522
+ title: '',
448
523
  backgroundTexture: '1.21.11/textures/gui/container/beacon.png',
449
524
  backgroundWidth: 230,
450
525
  backgroundHeight: 219,
@@ -460,6 +535,7 @@ export const inventoryDefinitions = makeInventoryDefinitions({
460
535
  backgroundTexture: '1.21.11/textures/gui/container/horse.png',
461
536
  backgroundWidth: 176,
462
537
  backgroundHeight: 166,
538
+ entityDisplay: { x: 26, y: 18, width: 52, height: 52 },
463
539
  slots: [
464
540
  { x: 8, y: 18, group: 'saddle', label: 'Saddle' },
465
541
  { x: 8, y: 36, group: 'armor', label: 'Horse Armor' },
@@ -473,6 +549,7 @@ export const inventoryDefinitions = makeInventoryDefinitions({
473
549
  backgroundTexture: '1.21.11/textures/gui/container/horse.png',
474
550
  backgroundWidth: 176,
475
551
  backgroundHeight: 166,
552
+ entityDisplay: { x: 26, y: 18, width: 52, height: 52 },
476
553
  slots: [
477
554
  // Saddle (0); slot 1 (horse armor) is absent for donkeys — gap is intentional
478
555
  { x: 8, y: 18, group: 'saddle', label: 'Saddle' },
@@ -488,6 +565,7 @@ export const inventoryDefinitions = makeInventoryDefinitions({
488
565
  backgroundTexture: '1.21.11/textures/gui/container/horse.png',
489
566
  backgroundWidth: 176,
490
567
  backgroundHeight: 166,
568
+ entityDisplay: { x: 26, y: 18, width: 52, height: 52 },
491
569
  slots: [
492
570
  { x: 8, y: 18, group: 'saddle', label: 'Carpet' },
493
571
  ...gridSlots(5, 3, 80, 18, 'chest').map((s, i) => i === 0 ? { ...s, index: 2 } : s),
@@ -583,8 +661,8 @@ export const inventoryDefinitions = makeInventoryDefinitions({
583
661
  backgroundWidth: 176,
584
662
  backgroundHeight: 166,
585
663
  slots: [
586
- ...gridSlots(3, 3, 30, 17, 'crafting'),
587
- { x: 124, y: 35, group: 'result', resultSlot: true },
664
+ ...gridSlots(3, 3, 26, 17, 'crafting'),
665
+ { x: 134, y: 35, group: 'result', resultSlot: true },
588
666
  ...playerInv(84),
589
667
  ],
590
668
  },
@@ -618,3 +696,18 @@ export const inventoryDefinitions = makeInventoryDefinitions({
618
696
  ],
619
697
  },
620
698
  })
699
+
700
+ /**
701
+ * Extra mc-assets texture paths that must be bundled by `scripts/generate-texture-imports.mjs`
702
+ * beyond the `backgroundTexture` fields already found in `inventoryDefinitions`.
703
+ *
704
+ * Add paths here when a component uses `textures.getGuiTextureUrl(path)` for a texture
705
+ * that is NOT already a `backgroundTexture` in any inventory definition (e.g. UI sprites).
706
+ *
707
+ * Format: versioned mc-assets path, e.g. "1.21.11/textures/gui/sprites/container/anvil/text_field.png"
708
+ */
709
+ export const registryExtraTextures: string[] = [
710
+ // Anvil rename input field sprites (used by AnvilInput component)
711
+ '1.21.11/textures/gui/sprites/container/anvil/text_field.png',
712
+ '1.21.11/textures/gui/sprites/container/anvil/text_field_disabled.png',
713
+ ]
@@ -45,3 +45,9 @@
45
45
  .mc-inv-root * {
46
46
  box-sizing: border-box;
47
47
  }
48
+
49
+ @keyframes mc-inv-focus-dash {
50
+ 0% { outline-offset: -2px; }
51
+ 50% { outline-offset: 0px; }
52
+ 100% { outline-offset: -2px; }
53
+ }
package/src/types.ts CHANGED
@@ -10,6 +10,21 @@ export interface ItemStack {
10
10
  lore?: string[]
11
11
  durability?: number
12
12
  maxDurability?: number
13
+ /**
14
+ * Override texture lookup key. When set, this path is used instead of the item `name`
15
+ * to resolve the item texture. Useful for custom resource packs or items that share a
16
+ * type ID but have distinct textures (e.g. potions, spawn eggs, dyed armor).
17
+ *
18
+ * The value is passed directly to `TextureConfig.getItemTextureUrl`.
19
+ * Example: `"item/dye_black"` or `"entity/spider/spider"`
20
+ */
21
+ textureKey?: string
22
+ /**
23
+ * Arbitrary debug identifier exposed as a `data-debug` attribute on the slot element.
24
+ * The mineflayer connector sets this to `"<type>:<metadata>"` by default, making it easy
25
+ * to inspect raw item IDs in browser DevTools without touching React internals.
26
+ */
27
+ debugKey?: string
13
28
  }
14
29
 
15
30
  export interface SlotState {
@@ -106,6 +121,13 @@ export interface ProgressBar {
106
121
  getMax: (props: Record<string, number>) => number
107
122
  }
108
123
 
124
+ export interface EntityDisplayArea {
125
+ x: number
126
+ y: number
127
+ width: number
128
+ height: number
129
+ }
130
+
109
131
  export interface InventoryTypeDefinition {
110
132
  name: string
111
133
  title: string
@@ -121,6 +143,14 @@ export interface InventoryTypeDefinition {
121
143
  windowType?: number | string
122
144
  hasTitle?: boolean
123
145
  extraData?: Record<string, unknown>
146
+ /** Bounds for the entity preview area (e.g. player model, horse model). */
147
+ entityDisplay?: EntityDisplayArea
148
+ /**
149
+ * When set, InventoryBackground will canvas-stitch the background texture:
150
+ * top (title + N container rows) + bottom (player inventory section) from
151
+ * the `generic_54.png` (176×222, 6-row) source. Applies only for N < 6.
152
+ */
153
+ containerRows?: number
124
154
  }
125
155
 
126
156
  export interface RecipeGuide {
@@ -0,0 +1,41 @@
1
+ import type { ItemStack } from '../types'
2
+
3
+ export function isItemEqual(a: ItemStack | null, b: ItemStack | null): boolean {
4
+ if (a === b) return true
5
+ if (!a || !b) return false
6
+ if (a.type !== b.type) return false
7
+ if ((a.name ?? '') !== (b.name ?? '')) return false
8
+ if ((a.metadata ?? 0) !== (b.metadata ?? 0)) return false
9
+ const aNbt = a.nbt ? JSON.stringify(a.nbt) : ''
10
+ const bNbt = b.nbt ? JSON.stringify(b.nbt) : ''
11
+ return aNbt === bNbt
12
+ }
13
+
14
+ export function getMaxStackSize(item: ItemStack): number {
15
+ const unstackable = [
16
+ 'diamond_sword', 'iron_sword', 'stone_sword', 'wooden_sword', 'golden_sword', 'netherite_sword',
17
+ 'diamond_pickaxe', 'iron_pickaxe', 'stone_pickaxe', 'wooden_pickaxe', 'golden_pickaxe', 'netherite_pickaxe',
18
+ 'diamond_axe', 'iron_axe', 'stone_axe', 'wooden_axe', 'golden_axe', 'netherite_axe',
19
+ 'diamond_shovel', 'iron_shovel', 'stone_shovel', 'wooden_shovel', 'golden_shovel', 'netherite_shovel',
20
+ 'diamond_hoe', 'iron_hoe', 'stone_hoe', 'wooden_hoe', 'golden_hoe', 'netherite_hoe',
21
+ 'bow', 'crossbow', 'trident', 'shield', 'fishing_rod', 'flint_and_steel', 'shears',
22
+ 'diamond_helmet', 'iron_helmet', 'golden_helmet', 'leather_helmet', 'chainmail_helmet', 'netherite_helmet', 'turtle_helmet',
23
+ 'diamond_chestplate', 'iron_chestplate', 'golden_chestplate', 'leather_chestplate', 'chainmail_chestplate', 'netherite_chestplate',
24
+ 'diamond_leggings', 'iron_leggings', 'golden_leggings', 'leather_leggings', 'chainmail_leggings', 'netherite_leggings',
25
+ 'diamond_boots', 'iron_boots', 'golden_boots', 'leather_boots', 'chainmail_boots', 'netherite_boots',
26
+ 'elytra', 'totem_of_undying', 'music_disc_13', 'music_disc_cat', 'music_disc_blocks', 'music_disc_chirp',
27
+ 'music_disc_far', 'music_disc_mall', 'music_disc_mellohi', 'music_disc_stal', 'music_disc_strad',
28
+ 'music_disc_ward', 'music_disc_11', 'music_disc_wait', 'music_disc_pigstep', 'music_disc_otherside',
29
+ 'music_disc_5', 'music_disc_relic',
30
+ 'carrot_on_a_stick', 'warped_fungus_on_a_stick', 'brush', 'mace',
31
+ ]
32
+ const stackTo16 = [
33
+ 'snowball', 'bucket', 'egg', 'ender_pearl', 'sign', 'banner', 'honey_bottle',
34
+ 'armor_stand', 'oak_sign', 'spruce_sign', 'birch_sign', 'jungle_sign', 'acacia_sign',
35
+ 'dark_oak_sign', 'mangrove_sign', 'cherry_sign', 'bamboo_sign', 'crimson_sign', 'warped_sign',
36
+ ]
37
+ const name = item.name ?? ''
38
+ if (unstackable.includes(name)) return 1
39
+ if (stackTo16.includes(name)) return 16
40
+ return 64
41
+ }