minecraft-inventory 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 +80 -10
- package/package.json +20 -8
- package/src/components/CursorItem/CursorItem.tsx +1 -10
- package/src/components/InventoryOverlay/InventoryOverlay.tsx +126 -56
- package/src/components/InventoryWindow/HotbarExtras.tsx +180 -0
- package/src/components/InventoryWindow/InventoryBackground.tsx +3 -3
- package/src/components/InventoryWindow/InventoryWindow.tsx +11 -0
- package/src/components/JEI/JEI.tsx +98 -29
- package/src/components/Notes/Notes.tsx +237 -0
- package/src/components/Notes/index.ts +2 -0
- package/src/components/RecipeGuide/RecipeInventoryView.tsx +5 -15
- package/src/components/Slot/Slot.tsx +49 -17
- package/src/components/Text/MessageFormatted.tsx +1 -1
- package/src/components/Tooltip/Tooltip.module.css +14 -14
- package/src/components/Tooltip/Tooltip.tsx +31 -24
- package/src/connector/demo.ts +4 -0
- package/src/connector/mineflayer.ts +145 -1
- package/src/connector/types.ts +39 -9
- package/src/context/TextureContext.tsx +17 -11
- package/src/generated/localTextures.ts +112 -0
- package/src/globals.d.ts +4 -0
- package/src/index.tsx +3 -2
- package/src/registry/index.ts +1 -0
- package/src/registry/inventories.ts +203 -195
- package/src/types.ts +4 -2
- package/src/utils/globalMouse.ts +14 -0
- package/src/components/Hotbar/Hotbar.tsx +0 -180
- package/src/components/Hotbar/index.ts +0 -1
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
import type { InventoryTypeDefinition } from '../types'
|
|
1
|
+
import type { InventoryTypeDefinition, SlotDefinition } from '../types'
|
|
2
2
|
|
|
3
3
|
const SLOT_SIZE = 18
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
type RawSlot = Omit<SlotDefinition, 'index'> & { index?: number }
|
|
6
|
+
|
|
7
|
+
function withSequentialIndexes(slots: RawSlot[]): SlotDefinition[] {
|
|
8
|
+
let next = 0
|
|
9
|
+
return slots.map((slot) => {
|
|
10
|
+
const index = slot.index !== undefined ? slot.index : next
|
|
11
|
+
next = index + 1
|
|
12
|
+
return { ...slot, index }
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function playerInv(yOffset: number): RawSlot[] {
|
|
17
|
+
const slots: RawSlot[] = []
|
|
11
18
|
for (let row = 0; row < 3; row++) {
|
|
12
19
|
for (let col = 0; col < 9; col++) {
|
|
13
20
|
slots.push({
|
|
14
|
-
index: invStartIndex + row * 9 + col,
|
|
15
21
|
x: 8 + col * SLOT_SIZE,
|
|
16
22
|
y: yOffset + row * SLOT_SIZE,
|
|
17
23
|
group: 'inventory',
|
|
@@ -20,7 +26,6 @@ function playerInv(
|
|
|
20
26
|
}
|
|
21
27
|
for (let col = 0; col < 9; col++) {
|
|
22
28
|
slots.push({
|
|
23
|
-
index: hotbarStartIndex + col,
|
|
24
29
|
x: 8 + col * SLOT_SIZE,
|
|
25
30
|
y: yOffset + 58,
|
|
26
31
|
group: 'hotbar',
|
|
@@ -29,9 +34,8 @@ function playerInv(
|
|
|
29
34
|
return slots
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
function hotbarSlots(yOffset: number,
|
|
37
|
+
function hotbarSlots(yOffset: number, xOffset = 8): RawSlot[] {
|
|
33
38
|
return Array.from({ length: 9 }, (_, col) => ({
|
|
34
|
-
index: indexOffset + col,
|
|
35
39
|
x: xOffset + col * SLOT_SIZE,
|
|
36
40
|
y: yOffset,
|
|
37
41
|
group: 'hotbar',
|
|
@@ -39,18 +43,16 @@ function hotbarSlots(yOffset: number, indexOffset = 36, xOffset = 8): InventoryT
|
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
function gridSlots(
|
|
42
|
-
startIndex: number,
|
|
43
46
|
cols: number,
|
|
44
47
|
rows: number,
|
|
45
48
|
x: number,
|
|
46
49
|
y: number,
|
|
47
50
|
group: string,
|
|
48
|
-
):
|
|
49
|
-
const slots:
|
|
51
|
+
): RawSlot[] {
|
|
52
|
+
const slots: RawSlot[] = []
|
|
50
53
|
for (let row = 0; row < rows; row++) {
|
|
51
54
|
for (let col = 0; col < cols; col++) {
|
|
52
55
|
slots.push({
|
|
53
|
-
index: startIndex + row * cols + col,
|
|
54
56
|
x: x + col * SLOT_SIZE,
|
|
55
57
|
y: y + row * SLOT_SIZE,
|
|
56
58
|
group,
|
|
@@ -60,89 +62,110 @@ function gridSlots(
|
|
|
60
62
|
return slots
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
// Slot positions within gui/widgets hotbar texture — matches layouts.mjs Hotbar:
|
|
66
|
+
// itemgrid at x: 3, y: 4, margin: 4, width: 9 (20px per slot: 16+4)
|
|
67
|
+
const HUD_SLOT_STEP = 20
|
|
68
|
+
function hudHotbarSlots(): RawSlot[] {
|
|
69
|
+
return Array.from({ length: 9 }, (_, col) => ({
|
|
70
|
+
// First slot carries explicit index: 36 so the running counter starts there
|
|
71
|
+
...(col === 0 ? { index: 36 } : {}),
|
|
72
|
+
x: 3.2 + col * HUD_SLOT_STEP,
|
|
73
|
+
y: 3.2,
|
|
74
|
+
group: 'hotbar',
|
|
75
|
+
}))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
type RawInventoryDefinition = Omit<InventoryTypeDefinition, 'slots'> & { slots: RawSlot[] }
|
|
79
|
+
|
|
80
|
+
const makeInventoryDefinitions = <T extends string>(
|
|
81
|
+
inv: Record<T, RawInventoryDefinition>,
|
|
82
|
+
): Record<T, InventoryTypeDefinition> =>
|
|
83
|
+
Object.fromEntries(
|
|
84
|
+
Object.entries(inv).map(([k, v]) => [
|
|
85
|
+
k,
|
|
86
|
+
{ ...(v as RawInventoryDefinition), slots: withSequentialIndexes((v as RawInventoryDefinition).slots) },
|
|
87
|
+
]),
|
|
88
|
+
) as Record<T, InventoryTypeDefinition>
|
|
89
|
+
|
|
90
|
+
export const inventoryDefinitions = makeInventoryDefinitions({
|
|
64
91
|
player: {
|
|
65
92
|
name: 'player',
|
|
66
93
|
title: 'Inventory',
|
|
67
|
-
backgroundTexture: 'gui/container/inventory',
|
|
94
|
+
backgroundTexture: '1.21.11/textures/gui/container/inventory.png',
|
|
68
95
|
backgroundWidth: 176,
|
|
69
96
|
backgroundHeight: 166,
|
|
70
97
|
slots: [
|
|
71
|
-
// Result
|
|
72
|
-
{
|
|
73
|
-
// Crafting 2x2
|
|
74
|
-
...gridSlots(
|
|
75
|
-
// Armor
|
|
76
|
-
{
|
|
77
|
-
{
|
|
78
|
-
{
|
|
79
|
-
{
|
|
80
|
-
// Offhand
|
|
81
|
-
{ index: 45, x: 77, y: 62, group: 'offhand', label: 'Offhand' },
|
|
98
|
+
// Result (0)
|
|
99
|
+
{ x: 154, y: 28, group: 'result', resultSlot: true },
|
|
100
|
+
// Crafting 2x2 (1-4)
|
|
101
|
+
...gridSlots(2, 2, 98, 18, 'crafting'),
|
|
102
|
+
// Armor head-to-feet (5-8)
|
|
103
|
+
{ x: 8, y: 8, group: 'armor', label: 'Head' },
|
|
104
|
+
{ x: 8, y: 26, group: 'armor', label: 'Chest' },
|
|
105
|
+
{ x: 8, y: 44, group: 'armor', label: 'Legs' },
|
|
106
|
+
{ x: 8, y: 62, group: 'armor', label: 'Feet' },
|
|
82
107
|
// Player inventory 9-35, hotbar 36-44
|
|
83
|
-
...playerInv(84
|
|
108
|
+
...playerInv(84),
|
|
109
|
+
// Offhand (45) — must come after playerInv so auto-index lands at 45
|
|
110
|
+
{ x: 77, y: 62, group: 'offhand', label: 'Offhand' },
|
|
84
111
|
],
|
|
85
112
|
},
|
|
86
113
|
|
|
87
114
|
chest: {
|
|
88
115
|
name: 'chest',
|
|
89
116
|
title: 'Chest',
|
|
90
|
-
backgroundTexture: 'gui/container/shulker_box',
|
|
117
|
+
backgroundTexture: '1.21.11/textures/gui/container/shulker_box.png',
|
|
91
118
|
backgroundWidth: 176,
|
|
92
119
|
backgroundHeight: 166,
|
|
93
120
|
playerInventoryOffset: { x: 8, y: 84 },
|
|
94
121
|
slots: [
|
|
95
|
-
...gridSlots(
|
|
96
|
-
|
|
97
|
-
...playerInv(84, 27, 54),
|
|
122
|
+
...gridSlots(9, 3, 8, 18, 'container'),
|
|
123
|
+
...playerInv(84),
|
|
98
124
|
],
|
|
99
125
|
},
|
|
100
126
|
|
|
101
127
|
generic_9x1: {
|
|
102
128
|
name: 'generic_9x1',
|
|
103
129
|
title: 'Container',
|
|
104
|
-
backgroundTexture: 'gui/container/shulker_box',
|
|
130
|
+
backgroundTexture: '1.21.11/textures/gui/container/shulker_box.png',
|
|
105
131
|
backgroundWidth: 176,
|
|
106
132
|
backgroundHeight: 96,
|
|
107
133
|
slots: [
|
|
108
|
-
...gridSlots(
|
|
109
|
-
|
|
110
|
-
...playerInv(14, 9, 36),
|
|
134
|
+
...gridSlots(9, 1, 8, 18, 'container'),
|
|
135
|
+
...playerInv(14),
|
|
111
136
|
],
|
|
112
137
|
},
|
|
113
138
|
|
|
114
139
|
large_chest: {
|
|
115
140
|
name: 'large_chest',
|
|
116
141
|
title: 'Large Chest',
|
|
117
|
-
backgroundTexture: 'gui/container/generic_54',
|
|
142
|
+
backgroundTexture: '1.21.11/textures/gui/container/generic_54.png',
|
|
118
143
|
backgroundWidth: 176,
|
|
119
144
|
backgroundHeight: 222,
|
|
120
145
|
playerInventoryOffset: { x: 8, y: 140 },
|
|
121
146
|
slots: [
|
|
122
|
-
...gridSlots(
|
|
123
|
-
|
|
124
|
-
...playerInv(140, 54, 81),
|
|
147
|
+
...gridSlots(9, 6, 8, 18, 'container'),
|
|
148
|
+
...playerInv(140),
|
|
125
149
|
],
|
|
126
150
|
},
|
|
127
151
|
|
|
128
152
|
crafting_table: {
|
|
129
153
|
name: 'crafting_table',
|
|
130
154
|
title: 'Crafting',
|
|
131
|
-
backgroundTexture: 'gui/container/crafting_table',
|
|
155
|
+
backgroundTexture: '1.21.11/textures/gui/container/crafting_table.png',
|
|
132
156
|
backgroundWidth: 176,
|
|
133
157
|
backgroundHeight: 166,
|
|
134
158
|
slots: [
|
|
135
|
-
{
|
|
136
|
-
...gridSlots(
|
|
137
|
-
|
|
138
|
-
...playerInv(84, 10, 37),
|
|
159
|
+
{ x: 124, y: 35, group: 'result', resultSlot: true },
|
|
160
|
+
...gridSlots(3, 3, 30, 17, 'crafting'),
|
|
161
|
+
...playerInv(84),
|
|
139
162
|
],
|
|
140
163
|
},
|
|
141
164
|
|
|
142
165
|
furnace: {
|
|
143
166
|
name: 'furnace',
|
|
144
167
|
title: 'Furnace',
|
|
145
|
-
backgroundTexture: 'gui/container/furnace',
|
|
168
|
+
backgroundTexture: '1.21.11/textures/gui/container/furnace.png',
|
|
146
169
|
backgroundWidth: 176,
|
|
147
170
|
backgroundHeight: 166,
|
|
148
171
|
properties: {
|
|
@@ -171,18 +194,17 @@ export const inventoryDefinitions: Record<string, InventoryTypeDefinition> = {
|
|
|
171
194
|
},
|
|
172
195
|
],
|
|
173
196
|
slots: [
|
|
174
|
-
{
|
|
175
|
-
{
|
|
176
|
-
{
|
|
177
|
-
|
|
178
|
-
...playerInv(84, 3, 30),
|
|
197
|
+
{ x: 56, y: 17, group: 'input' },
|
|
198
|
+
{ x: 56, y: 53, group: 'fuel', fuelSlot: true },
|
|
199
|
+
{ x: 116, y: 35, group: 'result', resultSlot: true },
|
|
200
|
+
...playerInv(84),
|
|
179
201
|
],
|
|
180
202
|
},
|
|
181
203
|
|
|
182
204
|
blast_furnace: {
|
|
183
205
|
name: 'blast_furnace',
|
|
184
206
|
title: 'Blast Furnace',
|
|
185
|
-
backgroundTexture: 'gui/container/blast_furnace',
|
|
207
|
+
backgroundTexture: '1.21.11/textures/gui/container/blast_furnace.png',
|
|
186
208
|
backgroundWidth: 176,
|
|
187
209
|
backgroundHeight: 166,
|
|
188
210
|
properties: {
|
|
@@ -210,17 +232,17 @@ export const inventoryDefinitions: Record<string, InventoryTypeDefinition> = {
|
|
|
210
232
|
},
|
|
211
233
|
],
|
|
212
234
|
slots: [
|
|
213
|
-
{
|
|
214
|
-
{
|
|
215
|
-
{
|
|
216
|
-
...playerInv(84
|
|
235
|
+
{ x: 56, y: 17, group: 'input' },
|
|
236
|
+
{ x: 56, y: 53, group: 'fuel', fuelSlot: true },
|
|
237
|
+
{ x: 116, y: 35, group: 'result', resultSlot: true },
|
|
238
|
+
...playerInv(84),
|
|
217
239
|
],
|
|
218
240
|
},
|
|
219
241
|
|
|
220
242
|
smoker: {
|
|
221
243
|
name: 'smoker',
|
|
222
244
|
title: 'Smoker',
|
|
223
|
-
backgroundTexture: 'gui/container/smoker',
|
|
245
|
+
backgroundTexture: '1.21.11/textures/gui/container/smoker.png',
|
|
224
246
|
backgroundWidth: 176,
|
|
225
247
|
backgroundHeight: 166,
|
|
226
248
|
properties: {
|
|
@@ -248,18 +270,17 @@ export const inventoryDefinitions: Record<string, InventoryTypeDefinition> = {
|
|
|
248
270
|
},
|
|
249
271
|
],
|
|
250
272
|
slots: [
|
|
251
|
-
{
|
|
252
|
-
{
|
|
253
|
-
{
|
|
254
|
-
|
|
255
|
-
...playerInv(84, 3, 30),
|
|
273
|
+
{ x: 56, y: 17, group: 'input' },
|
|
274
|
+
{ x: 56, y: 53, group: 'fuel', fuelSlot: true },
|
|
275
|
+
{ x: 116, y: 35, group: 'result', resultSlot: true },
|
|
276
|
+
...playerInv(84),
|
|
256
277
|
],
|
|
257
278
|
},
|
|
258
279
|
|
|
259
280
|
brewing_stand: {
|
|
260
281
|
name: 'brewing_stand',
|
|
261
282
|
title: 'Brewing Stand',
|
|
262
|
-
backgroundTexture: 'gui/container/brewing_stand',
|
|
283
|
+
backgroundTexture: '1.21.11/textures/gui/container/brewing_stand.png',
|
|
263
284
|
backgroundWidth: 176,
|
|
264
285
|
backgroundHeight: 166,
|
|
265
286
|
properties: {
|
|
@@ -285,52 +306,50 @@ export const inventoryDefinitions: Record<string, InventoryTypeDefinition> = {
|
|
|
285
306
|
},
|
|
286
307
|
],
|
|
287
308
|
slots: [
|
|
288
|
-
{
|
|
289
|
-
{
|
|
290
|
-
{
|
|
291
|
-
{
|
|
292
|
-
{
|
|
293
|
-
|
|
294
|
-
...playerInv(84, 5, 32),
|
|
309
|
+
{ x: 56, y: 51, group: 'bottle', label: 'Left' },
|
|
310
|
+
{ x: 79, y: 58, group: 'bottle', label: 'Center' },
|
|
311
|
+
{ x: 102, y: 51, group: 'bottle', label: 'Right' },
|
|
312
|
+
{ x: 79, y: 17, group: 'ingredient' },
|
|
313
|
+
{ x: 17, y: 17, group: 'fuel', fuelSlot: true },
|
|
314
|
+
...playerInv(84),
|
|
295
315
|
],
|
|
296
316
|
},
|
|
297
317
|
|
|
298
318
|
anvil: {
|
|
299
319
|
name: 'anvil',
|
|
300
320
|
title: 'Repair & Name',
|
|
301
|
-
backgroundTexture: 'gui/container/anvil',
|
|
321
|
+
backgroundTexture: '1.21.11/textures/gui/container/anvil.png',
|
|
302
322
|
backgroundWidth: 176,
|
|
303
323
|
backgroundHeight: 166,
|
|
304
324
|
properties: {
|
|
305
325
|
repairCost: { dataSlot: 0, description: 'Level cost' },
|
|
306
326
|
},
|
|
307
327
|
slots: [
|
|
308
|
-
{
|
|
309
|
-
{
|
|
310
|
-
{
|
|
311
|
-
|
|
312
|
-
...playerInv(84, 3, 30),
|
|
328
|
+
{ x: 27, y: 47, group: 'input' },
|
|
329
|
+
{ x: 76, y: 47, group: 'input' },
|
|
330
|
+
{ x: 134, y: 47, group: 'result', resultSlot: true },
|
|
331
|
+
...playerInv(84),
|
|
313
332
|
],
|
|
314
333
|
},
|
|
315
334
|
|
|
316
335
|
grindstone: {
|
|
317
336
|
name: 'grindstone',
|
|
318
337
|
title: 'Repair & Disenchant',
|
|
319
|
-
backgroundTexture: 'gui/container/grindstone',
|
|
338
|
+
backgroundTexture: '1.21.11/textures/gui/container/grindstone.png',
|
|
320
339
|
backgroundWidth: 176,
|
|
321
340
|
backgroundHeight: 166,
|
|
322
341
|
slots: [
|
|
323
|
-
{
|
|
324
|
-
{
|
|
325
|
-
{
|
|
326
|
-
...playerInv(84
|
|
342
|
+
{ x: 49, y: 19, group: 'input' },
|
|
343
|
+
{ x: 49, y: 40, group: 'input' },
|
|
344
|
+
{ x: 129, y: 34, group: 'result', resultSlot: true },
|
|
345
|
+
...playerInv(84),
|
|
327
346
|
],
|
|
328
347
|
},
|
|
329
348
|
|
|
330
349
|
enchanting_table: {
|
|
331
350
|
name: 'enchanting_table',
|
|
332
351
|
title: 'Enchant',
|
|
333
|
-
backgroundTexture: 'gui/container/enchanting_table',
|
|
352
|
+
backgroundTexture: '1.21.11/textures/gui/container/enchanting_table.png',
|
|
334
353
|
backgroundWidth: 176,
|
|
335
354
|
backgroundHeight: 166,
|
|
336
355
|
properties: {
|
|
@@ -343,270 +362,259 @@ export const inventoryDefinitions: Record<string, InventoryTypeDefinition> = {
|
|
|
343
362
|
bottomEnchantId: { dataSlot: 6, description: 'Bottom enchantment ID' },
|
|
344
363
|
},
|
|
345
364
|
slots: [
|
|
346
|
-
{
|
|
347
|
-
{
|
|
348
|
-
|
|
349
|
-
...playerInv(84, 2, 29),
|
|
365
|
+
{ x: 15, y: 47, group: 'enchant' },
|
|
366
|
+
{ x: 35, y: 47, group: 'lapis', label: 'Lapis Lazuli' },
|
|
367
|
+
...playerInv(84),
|
|
350
368
|
],
|
|
351
369
|
},
|
|
352
370
|
|
|
353
371
|
smithing_table: {
|
|
354
372
|
name: 'smithing_table',
|
|
355
373
|
title: 'Upgrade Gear',
|
|
356
|
-
backgroundTexture: 'gui/container/smithing',
|
|
357
|
-
guiTextureVersion: '1.21.4',
|
|
374
|
+
backgroundTexture: '1.21.11/textures/gui/container/smithing.png',
|
|
358
375
|
backgroundWidth: 176,
|
|
359
376
|
backgroundHeight: 166,
|
|
377
|
+
titleOffset: {
|
|
378
|
+
x: 40,
|
|
379
|
+
y: 13,
|
|
380
|
+
},
|
|
360
381
|
slots: [
|
|
361
|
-
{
|
|
362
|
-
{
|
|
363
|
-
{
|
|
364
|
-
{
|
|
365
|
-
|
|
366
|
-
...playerInv(84, 4, 31),
|
|
382
|
+
{ x: 8, y: 48, group: 'template', label: 'Template' },
|
|
383
|
+
{ x: 26, y: 48, group: 'input', label: 'Base' },
|
|
384
|
+
{ x: 44, y: 48, group: 'addition', label: 'Material' },
|
|
385
|
+
{ x: 98, y: 48, group: 'result', resultSlot: true },
|
|
386
|
+
...playerInv(84),
|
|
367
387
|
],
|
|
368
388
|
},
|
|
369
389
|
|
|
370
390
|
smithing_table_legacy: {
|
|
371
391
|
name: 'smithing_table_legacy',
|
|
372
392
|
title: 'Upgrade Gear',
|
|
373
|
-
backgroundTexture: 'gui/container/smithing',
|
|
393
|
+
backgroundTexture: '1.16.4/textures/gui/container/smithing.png',
|
|
374
394
|
backgroundWidth: 176,
|
|
375
395
|
backgroundHeight: 166,
|
|
396
|
+
titleOffset: {
|
|
397
|
+
x: 50,
|
|
398
|
+
y: 13,
|
|
399
|
+
},
|
|
376
400
|
slots: [
|
|
377
|
-
{
|
|
378
|
-
{
|
|
379
|
-
{
|
|
380
|
-
...playerInv(84
|
|
401
|
+
{ x: 27, y: 47, group: 'input', label: 'Base' },
|
|
402
|
+
{ x: 76, y: 47, group: 'addition', label: 'Material' },
|
|
403
|
+
{ x: 134, y: 47, group: 'result', resultSlot: true },
|
|
404
|
+
...playerInv(84),
|
|
381
405
|
],
|
|
382
406
|
},
|
|
383
407
|
|
|
384
408
|
hopper: {
|
|
385
409
|
name: 'hopper',
|
|
386
410
|
title: 'Item Hopper',
|
|
387
|
-
backgroundTexture: 'gui/container/hopper',
|
|
411
|
+
backgroundTexture: '1.21.11/textures/gui/container/hopper.png',
|
|
388
412
|
backgroundWidth: 176,
|
|
389
413
|
backgroundHeight: 133,
|
|
390
414
|
slots: [
|
|
391
|
-
...gridSlots(
|
|
392
|
-
...
|
|
393
|
-
|
|
394
|
-
x: 8 + (i % 9) * SLOT_SIZE,
|
|
395
|
-
y: 51 + Math.floor(i / 9) * SLOT_SIZE,
|
|
396
|
-
group: 'inventory' as const,
|
|
397
|
-
})),
|
|
398
|
-
...hotbarSlots(109, 32),
|
|
415
|
+
...gridSlots(5, 1, 44, 20, 'container'),
|
|
416
|
+
...gridSlots(9, 3, 8, 51, 'inventory'),
|
|
417
|
+
...hotbarSlots(109),
|
|
399
418
|
],
|
|
400
419
|
},
|
|
401
420
|
|
|
402
421
|
dispenser: {
|
|
403
422
|
name: 'dispenser',
|
|
404
423
|
title: 'Dispenser',
|
|
405
|
-
backgroundTexture: 'gui/container/dispenser',
|
|
424
|
+
backgroundTexture: '1.21.11/textures/gui/container/dispenser.png',
|
|
406
425
|
backgroundWidth: 176,
|
|
407
426
|
backgroundHeight: 166,
|
|
408
427
|
slots: [
|
|
409
|
-
...gridSlots(
|
|
410
|
-
|
|
411
|
-
...playerInv(84, 9, 36),
|
|
428
|
+
...gridSlots(3, 3, 62, 17, 'container'),
|
|
429
|
+
...playerInv(84),
|
|
412
430
|
],
|
|
413
431
|
},
|
|
414
432
|
|
|
415
433
|
dropper: {
|
|
416
434
|
name: 'dropper',
|
|
417
435
|
title: 'Dropper',
|
|
418
|
-
backgroundTexture: 'gui/container/dispenser',
|
|
436
|
+
backgroundTexture: '1.21.11/textures/gui/container/dispenser.png',
|
|
419
437
|
backgroundWidth: 176,
|
|
420
438
|
backgroundHeight: 166,
|
|
421
439
|
slots: [
|
|
422
|
-
...gridSlots(
|
|
423
|
-
...playerInv(84
|
|
440
|
+
...gridSlots(3, 3, 62, 17, 'container'),
|
|
441
|
+
...playerInv(84),
|
|
424
442
|
],
|
|
425
443
|
},
|
|
426
444
|
|
|
427
445
|
beacon: {
|
|
428
446
|
name: 'beacon',
|
|
429
447
|
title: 'Beacon',
|
|
430
|
-
backgroundTexture: 'gui/container/beacon',
|
|
448
|
+
backgroundTexture: '1.21.11/textures/gui/container/beacon.png',
|
|
431
449
|
backgroundWidth: 230,
|
|
432
450
|
backgroundHeight: 219,
|
|
433
451
|
slots: [
|
|
434
|
-
{
|
|
435
|
-
|
|
436
|
-
...playerInv(136, 1, 28),
|
|
452
|
+
{ x: 136, y: 110, group: 'payment', label: 'Payment' },
|
|
453
|
+
...playerInv(136),
|
|
437
454
|
],
|
|
438
455
|
},
|
|
439
456
|
|
|
440
457
|
horse: {
|
|
441
458
|
name: 'horse',
|
|
442
459
|
title: 'Horse',
|
|
443
|
-
backgroundTexture: 'gui/container/horse',
|
|
460
|
+
backgroundTexture: '1.21.11/textures/gui/container/horse.png',
|
|
444
461
|
backgroundWidth: 176,
|
|
445
462
|
backgroundHeight: 166,
|
|
446
463
|
slots: [
|
|
447
|
-
{
|
|
448
|
-
{
|
|
449
|
-
|
|
450
|
-
...playerInv(84, 2, 29),
|
|
464
|
+
{ x: 8, y: 18, group: 'saddle', label: 'Saddle' },
|
|
465
|
+
{ x: 8, y: 36, group: 'armor', label: 'Horse Armor' },
|
|
466
|
+
...playerInv(84),
|
|
451
467
|
],
|
|
452
468
|
},
|
|
453
469
|
|
|
454
470
|
donkey: {
|
|
455
471
|
name: 'donkey',
|
|
456
472
|
title: 'Donkey',
|
|
457
|
-
backgroundTexture: 'gui/container/horse',
|
|
473
|
+
backgroundTexture: '1.21.11/textures/gui/container/horse.png',
|
|
458
474
|
backgroundWidth: 176,
|
|
459
475
|
backgroundHeight: 166,
|
|
460
476
|
slots: [
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
y: 18 + Math.floor(i / 5) * SLOT_SIZE,
|
|
467
|
-
group: 'chest' as const,
|
|
468
|
-
})),
|
|
469
|
-
// inv: 17-43, hotbar: 44-52 (after 2 equipment + 15 chest)
|
|
470
|
-
...playerInv(84, 17, 44),
|
|
477
|
+
// Saddle (0); slot 1 (horse armor) is absent for donkeys — gap is intentional
|
|
478
|
+
{ x: 8, y: 18, group: 'saddle', label: 'Saddle' },
|
|
479
|
+
// Chest items start at index 2; explicit index jumps the counter over the gap
|
|
480
|
+
...gridSlots(5, 3, 80, 18, 'chest').map((s, i) => i === 0 ? { ...s, index: 2 } : s),
|
|
481
|
+
...playerInv(84),
|
|
471
482
|
],
|
|
472
483
|
},
|
|
473
484
|
|
|
474
485
|
llama: {
|
|
475
486
|
name: 'llama',
|
|
476
487
|
title: 'Llama',
|
|
477
|
-
backgroundTexture: 'gui/container/horse',
|
|
488
|
+
backgroundTexture: '1.21.11/textures/gui/container/horse.png',
|
|
478
489
|
backgroundWidth: 176,
|
|
479
490
|
backgroundHeight: 166,
|
|
480
491
|
slots: [
|
|
481
|
-
{
|
|
482
|
-
...
|
|
483
|
-
|
|
484
|
-
x: 80 + (i % 5) * SLOT_SIZE,
|
|
485
|
-
y: 18 + Math.floor(i / 5) * SLOT_SIZE,
|
|
486
|
-
group: 'chest' as const,
|
|
487
|
-
})),
|
|
488
|
-
...playerInv(84, 17, 44),
|
|
492
|
+
{ x: 8, y: 18, group: 'saddle', label: 'Carpet' },
|
|
493
|
+
...gridSlots(5, 3, 80, 18, 'chest').map((s, i) => i === 0 ? { ...s, index: 2 } : s),
|
|
494
|
+
...playerInv(84),
|
|
489
495
|
],
|
|
490
496
|
},
|
|
491
497
|
|
|
492
498
|
villager: {
|
|
493
499
|
name: 'villager',
|
|
494
500
|
title: 'Villager',
|
|
495
|
-
backgroundTexture: 'gui/container/villager2',
|
|
501
|
+
backgroundTexture: '1.14/textures/gui/container/villager2.png',
|
|
496
502
|
backgroundWidth: 276,
|
|
497
503
|
backgroundHeight: 166,
|
|
498
504
|
slots: [
|
|
499
|
-
{
|
|
500
|
-
{
|
|
501
|
-
{
|
|
502
|
-
...
|
|
503
|
-
|
|
504
|
-
x: 108 + (i % 9) * SLOT_SIZE,
|
|
505
|
-
y: 84 + Math.floor(i / 9) * SLOT_SIZE,
|
|
506
|
-
group: 'inventory' as const,
|
|
507
|
-
})),
|
|
508
|
-
...hotbarSlots(142, 30, 108),
|
|
505
|
+
{ x: 136, y: 37, group: 'trade_input1' },
|
|
506
|
+
{ x: 162, y: 37, group: 'trade_input2' },
|
|
507
|
+
{ x: 216, y: 37, group: 'trade_result', resultSlot: true },
|
|
508
|
+
...gridSlots(9, 3, 108, 84, 'inventory'),
|
|
509
|
+
...hotbarSlots(142, 108),
|
|
509
510
|
],
|
|
510
511
|
},
|
|
511
512
|
|
|
512
513
|
shulker_box: {
|
|
513
514
|
name: 'shulker_box',
|
|
514
515
|
title: 'Shulker Box',
|
|
515
|
-
backgroundTexture: 'gui/container/shulker_box',
|
|
516
|
+
backgroundTexture: '1.21.11/textures/gui/container/shulker_box.png',
|
|
516
517
|
backgroundWidth: 176,
|
|
517
518
|
backgroundHeight: 166,
|
|
518
519
|
slots: [
|
|
519
|
-
...gridSlots(
|
|
520
|
-
...playerInv(84
|
|
520
|
+
...gridSlots(9, 3, 8, 18, 'container'),
|
|
521
|
+
...playerInv(84),
|
|
521
522
|
],
|
|
522
523
|
},
|
|
523
524
|
|
|
524
525
|
barrel: {
|
|
525
526
|
name: 'barrel',
|
|
526
527
|
title: 'Barrel',
|
|
527
|
-
backgroundTexture: 'gui/container/shulker_box',
|
|
528
|
+
backgroundTexture: '1.21.11/textures/gui/container/shulker_box.png',
|
|
528
529
|
backgroundWidth: 176,
|
|
529
530
|
backgroundHeight: 166,
|
|
530
531
|
slots: [
|
|
531
|
-
...gridSlots(
|
|
532
|
-
...playerInv(84
|
|
532
|
+
...gridSlots(9, 3, 8, 18, 'container'),
|
|
533
|
+
...playerInv(84),
|
|
533
534
|
],
|
|
534
535
|
},
|
|
535
536
|
|
|
536
537
|
cartography_table: {
|
|
537
538
|
name: 'cartography_table',
|
|
538
539
|
title: 'Cartography Table',
|
|
539
|
-
backgroundTexture: 'gui/container/cartography_table',
|
|
540
|
+
backgroundTexture: '1.21.11/textures/gui/container/cartography_table.png',
|
|
540
541
|
backgroundWidth: 176,
|
|
541
542
|
backgroundHeight: 166,
|
|
542
543
|
slots: [
|
|
543
|
-
{
|
|
544
|
-
{
|
|
545
|
-
{
|
|
546
|
-
...playerInv(84
|
|
544
|
+
{ x: 15, y: 15, group: 'input', label: 'Map' },
|
|
545
|
+
{ x: 15, y: 39, group: 'input', label: 'Paper/Map' },
|
|
546
|
+
{ x: 145, y: 39, group: 'result', resultSlot: true },
|
|
547
|
+
...playerInv(84),
|
|
547
548
|
],
|
|
548
549
|
},
|
|
549
550
|
|
|
550
551
|
loom: {
|
|
551
552
|
name: 'loom',
|
|
552
553
|
title: 'Loom',
|
|
553
|
-
backgroundTexture: 'gui/container/loom',
|
|
554
|
+
backgroundTexture: '1.21.11/textures/gui/container/loom.png',
|
|
554
555
|
backgroundWidth: 176,
|
|
555
556
|
backgroundHeight: 166,
|
|
556
557
|
slots: [
|
|
557
|
-
{
|
|
558
|
-
{
|
|
559
|
-
{
|
|
560
|
-
{
|
|
561
|
-
...playerInv(84
|
|
558
|
+
{ x: 13, y: 26, group: 'input', label: 'Banner' },
|
|
559
|
+
{ x: 33, y: 26, group: 'input', label: 'Dye' },
|
|
560
|
+
{ x: 23, y: 45, group: 'input', label: 'Pattern' },
|
|
561
|
+
{ x: 143, y: 58, group: 'result', resultSlot: true },
|
|
562
|
+
...playerInv(84),
|
|
562
563
|
],
|
|
563
564
|
},
|
|
564
565
|
|
|
565
566
|
stonecutter: {
|
|
566
567
|
name: 'stonecutter',
|
|
567
568
|
title: 'Stonecutter',
|
|
568
|
-
backgroundTexture: 'gui/container/stonecutter',
|
|
569
|
+
backgroundTexture: '1.21.11/textures/gui/container/stonecutter.png',
|
|
569
570
|
backgroundWidth: 176,
|
|
570
571
|
backgroundHeight: 166,
|
|
571
572
|
slots: [
|
|
572
|
-
{
|
|
573
|
-
{
|
|
574
|
-
...playerInv(84
|
|
573
|
+
{ x: 20, y: 33, group: 'input' },
|
|
574
|
+
{ x: 143, y: 33, group: 'result', resultSlot: true },
|
|
575
|
+
...playerInv(84),
|
|
575
576
|
],
|
|
576
577
|
},
|
|
577
578
|
|
|
578
|
-
lectern: {
|
|
579
|
-
name: 'lectern',
|
|
580
|
-
title: 'Lectern',
|
|
581
|
-
backgroundTexture: 'gui/container/lectern',
|
|
582
|
-
backgroundWidth: 176,
|
|
583
|
-
backgroundHeight: 166,
|
|
584
|
-
slots: [],
|
|
585
|
-
},
|
|
586
|
-
|
|
587
579
|
crafter: {
|
|
588
580
|
name: 'crafter',
|
|
589
581
|
title: 'Crafter',
|
|
590
|
-
backgroundTexture: 'gui/container/crafter',
|
|
591
|
-
guiTextureVersion: '1.21.4',
|
|
582
|
+
backgroundTexture: '1.21.11/textures/gui/container/crafter.png',
|
|
592
583
|
backgroundWidth: 176,
|
|
593
584
|
backgroundHeight: 166,
|
|
594
585
|
slots: [
|
|
595
|
-
...gridSlots(
|
|
596
|
-
{
|
|
597
|
-
...playerInv(84
|
|
586
|
+
...gridSlots(3, 3, 30, 17, 'crafting'),
|
|
587
|
+
{ x: 124, y: 35, group: 'result', resultSlot: true },
|
|
588
|
+
...playerInv(84),
|
|
598
589
|
],
|
|
599
590
|
},
|
|
600
591
|
|
|
601
592
|
creative: {
|
|
602
593
|
name: 'creative',
|
|
603
594
|
title: 'Creative Inventory',
|
|
604
|
-
backgroundTexture: 'gui/container/creative_inventory/tab_items',
|
|
595
|
+
backgroundTexture: '1.21.11/textures/gui/container/creative_inventory/tab_items.png',
|
|
605
596
|
backgroundWidth: 195,
|
|
606
597
|
backgroundHeight: 136,
|
|
607
598
|
slots: [
|
|
608
|
-
...gridSlots(
|
|
609
|
-
|
|
599
|
+
...gridSlots(9, 5, 9, 48, 'body'),
|
|
600
|
+
// Creative hotbar indices start at 0 (separate window mapping), explicit to override counter
|
|
601
|
+
...hotbarSlots(142).map((s, i) => ({ ...s, index: i })),
|
|
610
602
|
],
|
|
611
603
|
},
|
|
612
|
-
|
|
604
|
+
|
|
605
|
+
// Standalone hotbar HUD container — mirrors layouts.mjs `Hotbar`
|
|
606
|
+
// Background: gui/widgets (182×22 hotbar strip), slots at HUD pixel coords
|
|
607
|
+
// Indices 36–44 are the standard player hotbar
|
|
608
|
+
hotbar: {
|
|
609
|
+
name: 'hotbar',
|
|
610
|
+
title: '',
|
|
611
|
+
backgroundTexture: '1.15/textures/gui/widgets.png',
|
|
612
|
+
backgroundWidth: 182,
|
|
613
|
+
backgroundHeight: 22,
|
|
614
|
+
slots: [
|
|
615
|
+
// 9 hotbar slots (36–44) within the 182×22 hotbar strip.
|
|
616
|
+
// index: 36 on the first slot starts the running counter at 36.
|
|
617
|
+
...hudHotbarSlots(),
|
|
618
|
+
],
|
|
619
|
+
},
|
|
620
|
+
})
|