minecraft-inventory 0.1.21 → 0.1.23
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/package.json +1 -1
- package/src/components/InventoryOverlay/InventoryOverlay.tsx +1 -1
- package/src/components/InventoryWindow/AnvilCost.tsx +1 -2
- package/src/components/InventoryWindow/EnchantmentOptions.tsx +106 -20
- package/src/connector/mineflayer.ts +54 -5
- package/src/context/InventoryContext.tsx +5 -1
- package/src/generated/localTextures.ts +27 -0
- package/src/registry/inventories.ts +10 -0
package/package.json
CHANGED
|
@@ -12,9 +12,8 @@ export function AnvilCost({ properties, backgroundWidth }: AnvilCostProps) {
|
|
|
12
12
|
const { windowState } = useInventoryContext()
|
|
13
13
|
|
|
14
14
|
const cost = properties.repairCost ?? 0
|
|
15
|
-
if (cost <= 0) return null
|
|
16
|
-
|
|
17
15
|
const hasResult = windowState?.slots.some((s) => s.index === 2 && s.item !== null) ?? false
|
|
16
|
+
if (cost <= 0) return null
|
|
18
17
|
if (!hasResult) return null
|
|
19
18
|
|
|
20
19
|
const tooExpensive = cost >= 40
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
2
|
import { useInventoryContext } from '../../context/InventoryContext'
|
|
3
|
+
import { useTextures } from '../../context/TextureContext'
|
|
3
4
|
import { useScale } from '../../context/ScaleContext'
|
|
4
5
|
|
|
5
6
|
const ENCHANTMENT_NAMES: Record<number, string> = {
|
|
@@ -59,6 +60,8 @@ function toRoman(num: number): string {
|
|
|
59
60
|
return result
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
const SPRITE_BASE = '1.21.11/textures/gui/sprites/container/enchanting_table'
|
|
64
|
+
|
|
62
65
|
interface EnchantmentOptionsProps {
|
|
63
66
|
properties: Record<string, number>
|
|
64
67
|
x: number
|
|
@@ -72,8 +75,27 @@ const OPTION_KEYS = [
|
|
|
72
75
|
]
|
|
73
76
|
|
|
74
77
|
export function EnchantmentOptions({ properties, x, y }: EnchantmentOptionsProps) {
|
|
75
|
-
const { sendAction } = useInventoryContext()
|
|
78
|
+
const { sendAction, resolveEnchantmentName } = useInventoryContext()
|
|
79
|
+
const textures = useTextures()
|
|
76
80
|
const { scale } = useScale()
|
|
81
|
+
const [hoveredSlot, setHoveredSlot] = useState<number | null>(null)
|
|
82
|
+
|
|
83
|
+
const getName = (id: number): string => {
|
|
84
|
+
if (id < 0) return '???'
|
|
85
|
+
return resolveEnchantmentName?.(id) ?? ENCHANTMENT_NAMES[id] ?? `Enchant #${id}`
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const getSlotSprite = (disabled: boolean, hovered: boolean) => {
|
|
89
|
+
if (disabled) return textures.getGuiTextureUrl(`${SPRITE_BASE}/enchantment_slot_disabled.png`)
|
|
90
|
+
if (hovered) return textures.getGuiTextureUrl(`${SPRITE_BASE}/enchantment_slot_highlighted.png`)
|
|
91
|
+
return textures.getGuiTextureUrl(`${SPRITE_BASE}/enchantment_slot.png`)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const getLevelSprite = (slot: number, disabled: boolean) => {
|
|
95
|
+
const n = slot + 1
|
|
96
|
+
if (disabled) return textures.getGuiTextureUrl(`${SPRITE_BASE}/level_${n}_disabled.png`)
|
|
97
|
+
return textures.getGuiTextureUrl(`${SPRITE_BASE}/level_${n}.png`)
|
|
98
|
+
}
|
|
77
99
|
|
|
78
100
|
return (
|
|
79
101
|
<div
|
|
@@ -90,36 +112,100 @@ export function EnchantmentOptions({ properties, x, y }: EnchantmentOptionsProps
|
|
|
90
112
|
const level = properties[levelKey] ?? 0
|
|
91
113
|
const enchId = properties[idKey] ?? -1
|
|
92
114
|
const levelClue = properties[clueKey] ?? 0
|
|
93
|
-
const name = ENCHANTMENT_NAMES[enchId] ?? (enchId >= 0 ? `Enchant #${enchId}` : '???')
|
|
94
115
|
const disabled = level <= 0
|
|
116
|
+
const hovered = hoveredSlot === i && !disabled
|
|
117
|
+
const name = getName(enchId)
|
|
95
118
|
const levelSuffix = levelClue > 0 ? ` ${toRoman(levelClue)}` : ''
|
|
119
|
+
// Vanilla colors
|
|
120
|
+
const nameColor = disabled ? '#342F25' : hovered ? '#FFFF80' : '#685E4A'
|
|
121
|
+
const costColor = disabled ? '#407F10' : '#80FF20'
|
|
96
122
|
|
|
97
123
|
return (
|
|
98
124
|
<div
|
|
99
125
|
key={i}
|
|
100
126
|
onClick={() => !disabled && sendAction({ type: 'enchant', enchantIndex: slot })}
|
|
127
|
+
onMouseEnter={() => setHoveredSlot(i)}
|
|
128
|
+
onMouseLeave={() => setHoveredSlot(null)}
|
|
101
129
|
style={{
|
|
130
|
+
position: 'relative',
|
|
102
131
|
width: 108 * scale,
|
|
103
132
|
height: 19 * scale,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
padding: `0 ${4 * scale}px`,
|
|
107
|
-
gap: 4 * scale,
|
|
108
|
-
background: disabled ? 'rgba(0,0,0,0.3)' : 'rgba(0,60,0,0.5)',
|
|
109
|
-
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
110
|
-
border: `${scale}px solid ${disabled ? '#333333' : '#446644'}`,
|
|
111
|
-
boxSizing: 'border-box',
|
|
112
|
-
fontSize: 6 * scale,
|
|
113
|
-
fontFamily: "'Minecraft', monospace",
|
|
114
|
-
color: disabled ? '#555555' : '#80c060',
|
|
133
|
+
cursor: disabled ? 'default' : 'pointer',
|
|
134
|
+
overflow: 'hidden',
|
|
115
135
|
}}
|
|
116
136
|
>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
137
|
+
{/* Background sprite */}
|
|
138
|
+
<img
|
|
139
|
+
src={getSlotSprite(disabled, hovered)}
|
|
140
|
+
alt=""
|
|
141
|
+
aria-hidden
|
|
142
|
+
draggable={false}
|
|
143
|
+
style={{
|
|
144
|
+
position: 'absolute',
|
|
145
|
+
left: 0,
|
|
146
|
+
top: 0,
|
|
147
|
+
width: 108 * scale,
|
|
148
|
+
height: 19 * scale,
|
|
149
|
+
imageRendering: 'pixelated',
|
|
150
|
+
}}
|
|
151
|
+
/>
|
|
152
|
+
{/* Level icon (16×16 at +1,+1) */}
|
|
153
|
+
{!disabled && (
|
|
154
|
+
<img
|
|
155
|
+
src={getLevelSprite(i, disabled)}
|
|
156
|
+
alt=""
|
|
157
|
+
aria-hidden
|
|
158
|
+
draggable={false}
|
|
159
|
+
style={{
|
|
160
|
+
position: 'absolute',
|
|
161
|
+
left: 1 * scale,
|
|
162
|
+
top: 1 * scale,
|
|
163
|
+
width: 16 * scale,
|
|
164
|
+
height: 16 * scale,
|
|
165
|
+
imageRendering: 'pixelated',
|
|
166
|
+
}}
|
|
167
|
+
/>
|
|
168
|
+
)}
|
|
169
|
+
{/* Enchantment name text (at +20, +2) */}
|
|
170
|
+
{!disabled && (
|
|
171
|
+
<span
|
|
172
|
+
style={{
|
|
173
|
+
position: 'absolute',
|
|
174
|
+
left: 20 * scale,
|
|
175
|
+
top: 2 * scale,
|
|
176
|
+
fontSize: 8 * scale,
|
|
177
|
+
fontFamily: "'Minecraft', monospace",
|
|
178
|
+
color: nameColor,
|
|
179
|
+
whiteSpace: 'nowrap',
|
|
180
|
+
overflow: 'hidden',
|
|
181
|
+
textOverflow: 'clip',
|
|
182
|
+
maxWidth: 70 * scale,
|
|
183
|
+
lineHeight: `${16 * scale}px`,
|
|
184
|
+
textShadow: 'none',
|
|
185
|
+
}}
|
|
186
|
+
>
|
|
187
|
+
{`${name}${levelSuffix}`}
|
|
188
|
+
</span>
|
|
189
|
+
)}
|
|
190
|
+
{/* Cost number (right-aligned, vertically centered) */}
|
|
191
|
+
{!disabled && (
|
|
192
|
+
<span
|
|
193
|
+
style={{
|
|
194
|
+
position: 'absolute',
|
|
195
|
+
right: 2 * scale,
|
|
196
|
+
top: 0,
|
|
197
|
+
height: 19 * scale,
|
|
198
|
+
display: 'flex',
|
|
199
|
+
alignItems: 'center',
|
|
200
|
+
fontSize: 8 * scale,
|
|
201
|
+
fontFamily: "'Minecraft', monospace",
|
|
202
|
+
color: costColor,
|
|
203
|
+
textShadow: 'none',
|
|
204
|
+
}}
|
|
205
|
+
>
|
|
206
|
+
{level}
|
|
207
|
+
</span>
|
|
208
|
+
)}
|
|
123
209
|
</div>
|
|
124
210
|
)
|
|
125
211
|
})}
|
|
@@ -52,6 +52,26 @@ export interface MineflayerConnectorOptions {
|
|
|
52
52
|
* Return a human-readable string for display.
|
|
53
53
|
*/
|
|
54
54
|
formatTitle?: (rawTitle: any) => string
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Optional client-side anvil cost calculator. Called when items in an anvil
|
|
58
|
+
* window change to compute repairCost instantly (before the server's
|
|
59
|
+
* craft_progress_bar packet arrives). Receives the two input slot items.
|
|
60
|
+
* Return the XP cost, or null/0 to clear. Server packets will override this.
|
|
61
|
+
*
|
|
62
|
+
* @example Using prismarine-item:
|
|
63
|
+
* ```ts
|
|
64
|
+
* const Item = require('prismarine-item')(bot.registry)
|
|
65
|
+
* createMineflayerConnector(bot, {
|
|
66
|
+
* computeAnvilCost: (item1, item2) => {
|
|
67
|
+
* if (!item1) return null
|
|
68
|
+
* const { xpCost } = Item.anvil(item1, item2, bot.game.gameMode === 'creative')
|
|
69
|
+
* return xpCost
|
|
70
|
+
* },
|
|
71
|
+
* })
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
computeAnvilCost?: (itemOne: RawSlot | null, itemTwo: RawSlot | null) => number | null
|
|
55
75
|
}
|
|
56
76
|
|
|
57
77
|
function makeSlotConverter(itemMapper?: MineflayerConnectorOptions['itemMapper']) {
|
|
@@ -138,6 +158,7 @@ export function createMineflayerConnector(bot: MineflayerBot, options?: Mineflay
|
|
|
138
158
|
const convert = makeSlotConverter(options?.itemMapper)
|
|
139
159
|
const hotbarOnly = options?.hotbarOnly ?? false
|
|
140
160
|
const formatTitle = options?.formatTitle
|
|
161
|
+
const computeAnvilCost = options?.computeAnvilCost
|
|
141
162
|
|
|
142
163
|
// Track window properties (furnace progress, enchant levels, etc.)
|
|
143
164
|
const windowProperties: Record<string, number> = {}
|
|
@@ -297,6 +318,27 @@ export function createMineflayerConnector(bot: MineflayerBot, options?: Mineflay
|
|
|
297
318
|
}
|
|
298
319
|
}
|
|
299
320
|
|
|
321
|
+
/** Compute anvil cost client-side if callback is provided and window is anvil. */
|
|
322
|
+
function tryComputeAnvilCost() {
|
|
323
|
+
if (!computeAnvilCost || !currentWindowType) return
|
|
324
|
+
const resolved = getInventoryType(currentWindowType)
|
|
325
|
+
if (resolved?.name !== 'anvil') return
|
|
326
|
+
const win = bot.currentWindow
|
|
327
|
+
if (!win) return
|
|
328
|
+
const item1 = (win.slots[0] as RawSlot | null) ?? null
|
|
329
|
+
const item2 = (win.slots[1] as RawSlot | null) ?? null
|
|
330
|
+
try {
|
|
331
|
+
const cost = item1 ? computeAnvilCost(item1, item2) : null
|
|
332
|
+
// Only SET client cost, never delete server-provided values.
|
|
333
|
+
// The server's craft_progress_bar will send 0 to clear when appropriate.
|
|
334
|
+
if (cost != null && cost > 0) {
|
|
335
|
+
windowProperties.repairCost = cost
|
|
336
|
+
}
|
|
337
|
+
} catch (err) {
|
|
338
|
+
// Client-side computation failed — rely on server cost
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
300
342
|
const onWindowOpen = () => {
|
|
301
343
|
const state = buildWindowState()
|
|
302
344
|
if (state) emit({ type: 'windowOpen', state })
|
|
@@ -307,6 +349,7 @@ export function createMineflayerConnector(bot: MineflayerBot, options?: Mineflay
|
|
|
307
349
|
}
|
|
308
350
|
|
|
309
351
|
const onSetSlot = () => {
|
|
352
|
+
tryComputeAnvilCost()
|
|
310
353
|
const state = buildWindowState()
|
|
311
354
|
if (state) emit({ type: 'windowUpdate', state })
|
|
312
355
|
emit({ type: 'playerUpdate', state: buildPlayerState() })
|
|
@@ -496,11 +539,17 @@ export function createMineflayerConnector(bot: MineflayerBot, options?: Mineflay
|
|
|
496
539
|
return
|
|
497
540
|
}
|
|
498
541
|
|
|
499
|
-
if (action.type === 'rename' && win && isAnvilWindow(win)) {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
if (
|
|
542
|
+
if (action.type === 'rename' && win && isAnvilWindow(win) && ext._client) {
|
|
543
|
+
// Send name_item packet directly — don't use mineflayer's win.rename()
|
|
544
|
+
// because it tries to transfer items from player inventory into anvil,
|
|
545
|
+
// which fails when the user already placed items via the UI.
|
|
546
|
+
if (ext.supportFeature?.('useMCItemName')) {
|
|
547
|
+
if (!ext._client.registerChannel) return
|
|
548
|
+
ext._client.registerChannel('MC|ItemName', 'string')
|
|
549
|
+
ext._client.writeChannel?.('MC|ItemName', action.text)
|
|
550
|
+
} else {
|
|
551
|
+
ext._client.write('name_item', { name: action.text })
|
|
552
|
+
}
|
|
504
553
|
return
|
|
505
554
|
}
|
|
506
555
|
|
|
@@ -49,6 +49,8 @@ export interface InventoryContextValue {
|
|
|
49
49
|
dragEndedRef: React.MutableRefObject<boolean>
|
|
50
50
|
/** When true, empty slot labels (Head, Chest, Legs, etc.) are not rendered */
|
|
51
51
|
noPlaceholders: boolean
|
|
52
|
+
/** Optional resolver for enchantment ID → display name (version-aware) */
|
|
53
|
+
resolveEnchantmentName?: (id: number) => string | undefined
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
const InventoryContext = createContext<InventoryContextValue | null>(null)
|
|
@@ -64,9 +66,10 @@ interface InventoryProviderProps {
|
|
|
64
66
|
children: React.ReactNode
|
|
65
67
|
noDragSpread?: boolean
|
|
66
68
|
noPlaceholders?: boolean
|
|
69
|
+
resolveEnchantmentName?: (id: number) => string | undefined
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
export function InventoryProvider({ connector, children, noDragSpread = false, noPlaceholders = false }: InventoryProviderProps) {
|
|
72
|
+
export function InventoryProvider({ connector, children, noDragSpread = false, noPlaceholders = false, resolveEnchantmentName }: InventoryProviderProps) {
|
|
70
73
|
const [windowState, setWindowState] = useState<InventoryWindowState | null>(
|
|
71
74
|
() => connector?.getWindowState() ?? null,
|
|
72
75
|
)
|
|
@@ -318,6 +321,7 @@ export function InventoryProvider({ connector, children, noDragSpread = false, n
|
|
|
318
321
|
pKeyDigit,
|
|
319
322
|
setPKeyDigit,
|
|
320
323
|
dragEndedRef,
|
|
324
|
+
resolveEnchantmentName,
|
|
321
325
|
}
|
|
322
326
|
|
|
323
327
|
valueRef.current = value
|
|
@@ -35,6 +35,15 @@ import _gui_sprites_container_smoker_lit_progress from 'mc-assets/dist/other-tex
|
|
|
35
35
|
import _gui_sprites_container_smoker_burn_progress from 'mc-assets/dist/other-textures/latest/gui/sprites/container/smoker/burn_progress.png'
|
|
36
36
|
import _gui_sprites_container_brewing_stand_brew_progress from 'mc-assets/dist/other-textures/latest/gui/sprites/container/brewing_stand/brew_progress.png'
|
|
37
37
|
import _gui_sprites_container_brewing_stand_fuel_length from 'mc-assets/dist/other-textures/latest/gui/sprites/container/brewing_stand/fuel_length.png'
|
|
38
|
+
import _gui_sprites_container_enchanting_table_enchantment_slot from 'mc-assets/dist/other-textures/latest/gui/sprites/container/enchanting_table/enchantment_slot.png'
|
|
39
|
+
import _gui_sprites_container_enchanting_table_enchantment_slot_disabled from 'mc-assets/dist/other-textures/latest/gui/sprites/container/enchanting_table/enchantment_slot_disabled.png'
|
|
40
|
+
import _gui_sprites_container_enchanting_table_enchantment_slot_highlighted from 'mc-assets/dist/other-textures/latest/gui/sprites/container/enchanting_table/enchantment_slot_highlighted.png'
|
|
41
|
+
import _gui_sprites_container_enchanting_table_level_1 from 'mc-assets/dist/other-textures/latest/gui/sprites/container/enchanting_table/level_1.png'
|
|
42
|
+
import _gui_sprites_container_enchanting_table_level_2 from 'mc-assets/dist/other-textures/latest/gui/sprites/container/enchanting_table/level_2.png'
|
|
43
|
+
import _gui_sprites_container_enchanting_table_level_3 from 'mc-assets/dist/other-textures/latest/gui/sprites/container/enchanting_table/level_3.png'
|
|
44
|
+
import _gui_sprites_container_enchanting_table_level_1_disabled from 'mc-assets/dist/other-textures/latest/gui/sprites/container/enchanting_table/level_1_disabled.png'
|
|
45
|
+
import _gui_sprites_container_enchanting_table_level_2_disabled from 'mc-assets/dist/other-textures/latest/gui/sprites/container/enchanting_table/level_2_disabled.png'
|
|
46
|
+
import _gui_sprites_container_enchanting_table_level_3_disabled from 'mc-assets/dist/other-textures/latest/gui/sprites/container/enchanting_table/level_3_disabled.png'
|
|
38
47
|
|
|
39
48
|
/**
|
|
40
49
|
* Versioned texture path → bundled asset URL (or undefined for remote fallback).
|
|
@@ -75,6 +84,15 @@ export const bundledTextureMap: Record<string, string | undefined> = {
|
|
|
75
84
|
'1.21.11/textures/gui/sprites/container/smoker/burn_progress.png': _gui_sprites_container_smoker_burn_progress,
|
|
76
85
|
'1.21.11/textures/gui/sprites/container/brewing_stand/brew_progress.png': _gui_sprites_container_brewing_stand_brew_progress,
|
|
77
86
|
'1.21.11/textures/gui/sprites/container/brewing_stand/fuel_length.png': _gui_sprites_container_brewing_stand_fuel_length,
|
|
87
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/enchantment_slot.png': _gui_sprites_container_enchanting_table_enchantment_slot,
|
|
88
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/enchantment_slot_disabled.png': _gui_sprites_container_enchanting_table_enchantment_slot_disabled,
|
|
89
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/enchantment_slot_highlighted.png': _gui_sprites_container_enchanting_table_enchantment_slot_highlighted,
|
|
90
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_1.png': _gui_sprites_container_enchanting_table_level_1,
|
|
91
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_2.png': _gui_sprites_container_enchanting_table_level_2,
|
|
92
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_3.png': _gui_sprites_container_enchanting_table_level_3,
|
|
93
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_1_disabled.png': _gui_sprites_container_enchanting_table_level_1_disabled,
|
|
94
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_2_disabled.png': _gui_sprites_container_enchanting_table_level_2_disabled,
|
|
95
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_3_disabled.png': _gui_sprites_container_enchanting_table_level_3_disabled,
|
|
78
96
|
}
|
|
79
97
|
|
|
80
98
|
|
|
@@ -116,6 +134,15 @@ export const allTexturePaths: readonly string[] = [
|
|
|
116
134
|
'gui/sprites/container/smoker/burn_progress.png',
|
|
117
135
|
'gui/sprites/container/brewing_stand/brew_progress.png',
|
|
118
136
|
'gui/sprites/container/brewing_stand/fuel_length.png',
|
|
137
|
+
'gui/sprites/container/enchanting_table/enchantment_slot.png',
|
|
138
|
+
'gui/sprites/container/enchanting_table/enchantment_slot_disabled.png',
|
|
139
|
+
'gui/sprites/container/enchanting_table/enchantment_slot_highlighted.png',
|
|
140
|
+
'gui/sprites/container/enchanting_table/level_1.png',
|
|
141
|
+
'gui/sprites/container/enchanting_table/level_2.png',
|
|
142
|
+
'gui/sprites/container/enchanting_table/level_3.png',
|
|
143
|
+
'gui/sprites/container/enchanting_table/level_1_disabled.png',
|
|
144
|
+
'gui/sprites/container/enchanting_table/level_2_disabled.png',
|
|
145
|
+
'gui/sprites/container/enchanting_table/level_3_disabled.png',
|
|
119
146
|
]
|
|
120
147
|
|
|
121
148
|
/**
|
|
@@ -749,4 +749,14 @@ export const registryExtraTextures: string[] = [
|
|
|
749
749
|
// Brewing stand progress bar sprites
|
|
750
750
|
'1.21.11/textures/gui/sprites/container/brewing_stand/brew_progress.png',
|
|
751
751
|
'1.21.11/textures/gui/sprites/container/brewing_stand/fuel_length.png',
|
|
752
|
+
// Enchanting table slot backgrounds & level icons
|
|
753
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/enchantment_slot.png',
|
|
754
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/enchantment_slot_disabled.png',
|
|
755
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/enchantment_slot_highlighted.png',
|
|
756
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_1.png',
|
|
757
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_2.png',
|
|
758
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_3.png',
|
|
759
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_1_disabled.png',
|
|
760
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_2_disabled.png',
|
|
761
|
+
'1.21.11/textures/gui/sprites/container/enchanting_table/level_3_disabled.png',
|
|
752
762
|
]
|